파일 기반 암호화

Android 7.0 이상에서는 파일 기반 암호화(FBE)를 지원합니다. 파일 기반 암호화를 사용하면 개별적으로 잠금 해제 가능한 여러 키를 사용하여 여러 파일을 암호화할 수 있습니다.

이 문서에서는 새 기기에 파일 기반 암호화를 사용 설정하는 방법, 그리고 시스템 애플리케이션이 어떻게 Direct Boot API를 사용하여 가장 안전한 최상의 환경을 제공할 수 있는지에 관해 설명합니다.

Android 10 및 이후 버전으로 출시되는 모든 기기는 파일 기반 암호화를 사용해야 합니다.

직접 부팅

파일 기반 암호화는 Android 7.0에서 새로 도입된 기능인 직접 부팅을 지원합니다. 직접 부팅을 사용하면 암호화된 기기를 잠금 화면에 바로 부팅할 수 있습니다. 이전에는 전체 디스크 암호화(FDE)를 사용하는 암호화된 기기에서 사용자는 데이터에 액세스하려면 사용자 인증 정보를 제공해야 했으며 휴대전화는 가장 기본적인 작업만 실행할 수 있었습니다. 예를 들면 알람이 작동하지 않았고 접근성 서비스에 액세스할 수 없었고 휴대전화로 전화를 받을 수 없었으며, 기본적인 비상 전화만 사용 가능했습니다.

애플리케이션이 암호화를 인지하도록 하기 위한 파일 기반 암호화(FBE)와 새로운 API의 도입으로 이제는 앱이 제한된 환경에서 작동할 수 있습니다. 이는 사용자가 사용자 인증 정보를 제공하기 전에 발생할 수 있으며, 비공개 사용자 정보는 계속해서 보호됩니다.

FBE가 사용 설정된 기기에서는 기기의 각 사용자가 두 개의 저장소 위치를 애플리케이션에 사용할 수 있습니다.

  • 사용자 인증 정보 암호화(CE) 저장소는 기본 저장소 위치이며, 사용자가 기기의 잠금을 해제한 후에만 사용할 수 있습니다.
  • 기기 암호화(DE) 저장소는 직접 부팅 모드 시 그리고 사용자가 기기의 잠금을 해제한 후에 모두 사용할 수 있는 저장소 위치입니다.

이렇게 구분할 경우 암호화가 더 이상 부팅 시점의 비밀번호에만 의존하지 않고 2명 이상의 사용자를 동시에 보호할 수 있으므로 직장 프로필이 훨씬 안전해집니다.

Direct Boot API는 암호화 인식 애플리케이션이 이러한 각 영역에 액세스할 수 있게 해줍니다. 잠금 화면에서 사용자 인증 정보를 처음 입력하는 것에 응답하여 또는 직장 프로필이 직장 보안 확인을 제공하는 경우 사용자의 CE 저장소가 잠금 해제될 때 애플리케이션에 이를 알려야 하는 필요성을 수용할 수 있도록 애플리케이션 수명 주기가 변경되었습니다. Android 7.0을 실행하는 기기는 FBE 구현 여부와 상관없이 이러한 새 API와 수명 주기를 지원해야 합니다. FBE가 없더라도 DE 및 CE 저장소는 항상 잠금 해제된 상태를 유지합니다.

AOSP(Android 오픈소스 프로젝트)에는 Ext4 및 F2FS 파일 시스템에서 파일 기반 암호화의 완전한 구현이 마련되어 있으며 요구사항을 충족하는 기기에서 사용 설정만 하면 됩니다. FBE를 사용하기로 결정한 제조업체는 사용된 단일 칩 시스템(SoC)에 따라 기능을 최적화하는 방법을 살펴보는 것이 좋습니다.

AOSP의 모든 필수 패키지는 직접 부팅 인식으로 업데이트되었습니다. 하지만 앱의 맞춤설정된 버전을 사용하는 기기 제조업체는 최소 다음과 같은 서비스를 제공하는 직접 부팅 인식 패키지가 있는지 확인해야 합니다.

  • 전화 서비스 및 다이얼러
  • 잠금 화면에 비밀번호를 입력하기 위한 입력 메서드

예시 및 소스

Android는 파일 기반 암호화의 참조 구현을 제공합니다. 여기서는 vold(system/vold)가 Android의 저장 기기 및 볼륨을 관리하는 기능을 제공합니다. FBE를 추가하면 여러 사용자의 CE 및 DE 키 관리를 지원하기 위한 여러 새로운 명령어가 vold에 주어집니다. 커널에서 파일 기반 암호화 기능을 사용하도록 한 핵심 변경사항 외에도 lockscreen 및 SystemUI를 비롯한 다수의 시스템 패키지가 FBE 및 직접 부팅 기능을 지원하도록 수정되었습니다. 수정된 사항은 다음과 같습니다.

  • AOSP 다이얼러(패캐지/앱/다이얼러)
  • 탁상 시계(패키지/앱/DeskClock)
  • LatinIME(패키지/inputmethods/LatinIME)*
  • 설정 앱(패키지/앱/설정)*
  • SystemUI(프레임워크/기반/패키지/SystemUI)*

* defaultToDeviceProtectedStorage 매니페스트 속성을 사용하는 시스템 애플리케이션

암호화를 인식하는 애플리케이션과 서비스의 추가적인 예를 확인하려면 AOSP 소스 트리의 프레임워크나 패키지 디렉터리에서 명령어 mangrep directBootAware를 실행하세요.

종속 항목

FBE의 AOSP 구현을 안전하게 사용하려면 기기가 다음과 같은 종속 항목을 충족해야 합니다.

  • Ext4 암호화 또는 F2FS 암호화를 위한 커널 지원.
  • HAL 1.0 및 이후 버전으로 Keymaster 지원. Keymaster 0.3은 필요한 기능을 제공하거나 암호화 키에 충분한 보호를 보장하지 않으므로 지원되지 않습니다.
  • Keymaster/키 저장소 및 게이트키퍼는 DE 키 보호 조치를 제공하여 승인되지 않은 OS(기기에 플래시된 맞춤 OS)가 쉽게 DE 키를 요청할 수 없도록 신뢰할 수 있는 실행 환경(TEE)에서 구현되어야 합니다.
  • 승인되지 않은 운영체제에서 DE 키에 액세스할 수 없도록 Keymaster 초기화에 바인딩된 신뢰할 수 있는 하드웨어 루트자체 검사 부팅이 필요합니다.

구현

가장 중요한 점은 알람 시계, 전화, 접근성 기능 등의 앱이 직접 부팅 개발자 문서에 따라 android:directBootAware로 만들어져야 한다는 것입니다.

커널 지원

Ext4 및 F2FS 암호화를 위한 커널 지원은 Android 공통 커널 3.18 및 이후 버전에서 제공됩니다. 버전 5.1 이상의 커널에서 사용 설정하려면 다음을 사용합니다.

CONFIG_FS_ENCRYPTION=y

이전 커널의 경우 기기의 userdata 파일 시스템이 Ext4라면 CONFIG_EXT4_ENCRYPTION=y를 사용하고 기기의 userdata 파일 시스템이 F2FS라면 CONFIG_F2FS_FS_ENCRYPTION=y를 사용합니다.

기기에서 채택 가능한 저장소를 지원하거나 내부 저장소에서 메타데이터 암호화를 사용한다면 메타데이터 암호화 문서에 설명한 대로 메타데이터 암호화에 필요한 커널 구성 옵션도 사용 설정합니다.

Ext4 또는 F2FS 암호화 기능 지원 외에도 기기 제조업체는 암호화 가속을 사용하여 파일 기반 암호화 속도를 높이고 사용자 환경을 개선해야 합니다. 예를 들어, ARM64 기반 기기에서 ARMv8 CE(암호화 확장 프로그램) 가속은 다음의 커널 구성 옵션을 설정하여 사용할 수 있습니다.

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

성능을 더욱 개선하고 전력 사용량을 줄이기 위해 기기 제조업체는 인라인 암호화 하드웨어를 구현하여 저장 장치와의 데이터 송수신 중에 데이터를 암호화/복호화할 수도 있습니다. Android 공통 커널(버전 4.14 이상)에는 하드웨어 및 공급업체 드라이버 지원이 제공될 때 인라인 암호화를 사용할 수 있는 프레임워크가 포함되어 있습니다. 인라인 암호화 프레임워크는 다음 커널 구성 옵션을 설정하여 사용할 수 있습니다.

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

기기에서 UFS 기반 저장소를 사용하는 경우 다음을 사용 설정합니다.

CONFIG_SCSI_UFS_CRYPTO=y

기기에서 eMMC 기반 저장소를 사용하는 경우 다음을 사용 설정합니다.

CONFIG_MMC_CRYPTO=y

파일 기반 암호화 사용 설정

기기에서 FBE를 사용 설정하려면 내부 저장소(userdata)에서 사용 설정해야 합니다. 이렇게 하면 채택 가능한 저장소에서 자동으로 FBE가 사용 설정됩니다. 그러나 채택 가능한 저장소의 암호화 형식은 필요한 경우 재정의될 수 있습니다.

내부 저장소

FBE는 userdatafstab 줄의 fs_mgr_flags 열에 fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] 옵션을 추가하여 사용 설정됩니다. 이 옵션은 내부 저장소의 암호화 형식을 정의합니다. 콜론으로 구분된 매개변수를 최대 세 개까지 포함할 수 있습니다.

  • contents_encryption_mode 매개변수는 파일 콘텐츠를 암호화하는 데 사용되는 암호화 알고리즘을 정의합니다. aes-256-xts 또는 adiantum이 될 수 있습니다. Android 11이므로 기본 알고리즘인 aes-256-xts를 지정할 수도 있습니다.
  • filenames_encryption_mode 매개변수는 파일 이름을 암호화하는 데 사용되는 암호화 알고리즘을 정의합니다. aes-256-cts, aes-256-heh, adiantum 또는 aes-256-hctr2이 될 수 있습니다. 매개변수가 지정되지 않은 경우 contents_encryption_modeaes-256-xts이면 aes-256-cts가, contents_encryption_modeadiantum이면 adiantum이 기본값으로 지정됩니다.
  • Android 11의 새로운 flags 매개변수는 + 문자로 구분된 플래그 목록입니다. 지원되는 플래그는 다음과 같습니다.
    • v1 플래그는 버전 1 암호화 정책을 선택하고 v2 플래그는 버전 2 암호화 정책을 선택합니다. 버전 2 암호화 정책은 더욱 안전하고 유연한 키 파생 함수를 사용합니다. Android 11 이상으로 출시된 기기(ro.product.first_api_level에 정의된 대로)는 v2를, Android 10 이하로 출시된 기기는 v1을 기본값으로 합니다.
    • inlinecrypt_optimized 플래그는 많은 수의 키를 효율적으로 처리하지 않는 인라인 암호화 하드웨어에 최적화된 암호화 형식을 선택합니다. 파일당 하나가 아닌 CE 또는 DE 키당 하나의 파일 콘텐츠 암호화 키를 도출하여 이를 실행합니다. 이에 따라 IV(초기화 벡터)의 생성이 조정됩니다.
    • emmc_optimized 플래그는 inlinecrypt_optimized와 비슷하지만 IV를 32비트로 제한하는 IV세대 메서드도 선택합니다. 이 플래그는 JEDEC eMMC v5.2 사양을 준수하는 인라인 암호화 하드웨어에서만 사용해야 하므로 32비트 IV만 지원합니다. 다른 인라인 암호화 하드웨어에서는 대신 inlinecrypt_optimized를 사용하세요. 이 플래그는 UFS 기반 저장소에서 사용하면 안 됩니다. UFS 사양에서는 64비트 IV를 사용할 수 있습니다.
    • 하드웨어 래핑 키를 지원하는 기기에서는 wrappedkey_v0 플래그를 통해 FBE에 하드웨어 래핑 키를 사용할 수 있습니다. inlinecrypt 마운트 옵션 및 inlinecrypt_optimized 또는 emmc_optimized 플래그와 함께만 사용할 수 있습니다.

인라인 암호화 하드웨어를 사용하지 않는다면 대부분의 기기에 권장되는 설정은 fileencryption=aes-256-xts입니다. 인라인 암호화 하드웨어를 사용하는 경우 대부분의 기기에 권장되는 설정은 fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized(또는 fileencryption=::inlinecrypt_optimized)입니다. AES 가속화가 없는 기기에서는 fileencryption=adiantum을 설정하여 AES 대신 Adiantum을 사용할 수 있습니다.

Android 14(AOSP 실험용)부터는 가속 암호화 명령을 지원하는 기기에서 파일 이름 암호화를 위해 AES-HCTR2가 선호됩니다. 하지만 최신 Android 커널만 AES-HCTR2를 지원합니다. 향후 Android 버전에서는 파일 이름 암호화의 기본 모드가 될 것입니다. 커널이 AES-HCTR2를 지원하는 경우 filenames_encryption_modeaes-256-hctr2로 설정하여 파일 이름 암호화를 사용 설정할 수 있습니다. fileencryption=aes-256-xts:aes-256-hctr2를 사용하는 것이 가장 간단합니다.

Android 10 이하로 출시된 기기의 경우 FSCRYPT_MODE_PRIVATE 파일 콘텐츠 암호화 모드의 사용을 명시하기 위해 fileencryption=ice도 허용됩니다. 이 모드는 Android 공통 커널에서 구현되지 않지만 맞춤 커널 패치를 사용하여 공급업체에서 구현할 수 있습니다. 이 모드에서 생성된 디스크 상의 형식은 공급업체에 따라 다릅니다. Android 11 이상을 사용하여 출시하는 기기에서는 이 모드를 더 이상 사용할 수 없고 대신 표준 암호화 형식을 사용해야 합니다.

기본적으로 파일 콘텐츠 암호화는 Linux 커널의 암호화 API를 사용합니다. 대신 인라인 암호화 하드웨어를 사용하려면 inlinecrypt 마운트 옵션도 추가합니다. 예를 들어, 전체 fstab 줄은 다음과 같이 표시될 수 있습니다.

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

채택 가능한 저장소

Android 9 이후로 FBE와 채택 가능한 저장소를 함께 사용할 수 있습니다.

또한, userdatafileencryption fstab 옵션을 지정하면 자동으로 채택 가능한 저장소에 FBE와 메타데이터 암호화가 모두 사용 설정됩니다. 하지만, PRODUCT_PROPERTY_OVERRIDES에 속성을 설정하여 채택 가능한 저장소에 FBE 및 메타데이터 암호화 형식을 재정의할 수 있습니다.

Android 11 이상으로 출시된 기기는 다음 속성을 사용합니다.

  • ro.crypto.volume.options(Android 11의 새로운 기능)는 채택 가능한 저장소에 FBE 암호화 형식을 선택합니다. fileencryption fstab 옵션의 인수와 동일한 구문을 사용하며 동일한 기본값을 갖습니다. 여기에서 무엇을 사용할지는 위의 fileencryption 권장사항을 참조하세요.
  • ro.crypto.volume.metadata.encryption은 채택 가능한 저장소에 메타데이터 암호화 형식을 선택합니다. 메타데이터 암호화 문서를 참조하세요.

Android 10 이하로 출시된 기기에서는 다음 속성을 사용합니다.

  • ro.crypto.volume.contents_mode는 콘텐츠 암호화 모드를 선택합니다. 이는 ro.crypto.volume.options의 콜론으로 구분된 첫 번째 필드와 동일합니다.
  • ro.crypto.volume.filenames_mode는 파일 이름 암호화 모드를 선택합니다. 이는 Android 10 이하로 출시된 기기의 기본값이 aes-256-heh인 경우를 제외하고 ro.crypto.volume.options의 콜론으로 구분된 두 번째 필드와 동일합니다. 이 값은 대부분의 기기에서 명시적으로 aes-256-cts로 재정의해야 합니다.
  • ro.crypto.fde_algorithmro.crypto.fde_sector_size는 채택 가능한 저장소에서 메타데이터 암호화 형식을 선택합니다. 메타데이터 암호화 문서를 참조하세요.

Keymaster에 통합

Keymaster HAL은 early_hal 클래스의 일부로 시작해야 합니다. FBE를 사용하려면 Keymaster가 post-fs-data 부팅 단계(vold가 초기 키를 설정하는 시점)에서 보내는 요청을 처리할 준비가 되어 있어야 하기 때문입니다.

디렉터리 제외

init/data의 모든 최상위 디렉터리에 시스템 DE 키를 적용합니다. 단, 암호화되지 않아야 하는 디렉터리(시스템 DE 키가 포함된 디렉터리와 사용자 CE 또는 DE 디렉터리가 포함된 디렉터리)는 예외입니다. 암호화 키는 재귀적으로 적용되며 하위 디렉터리에서 재정의할 수 없습니다.

Android 11 및 이후 버전에서는 init이 디렉터리에 적용하는 키를 init 석세스토리 스크립트에서 mkdir 명령어의 encryption=<action> 인수로 제어할 수 있습니다. <action>의 가능한 값은 Android Init 언어 리드미에서 확인할 수 있습니다.

Android 10에서 init 암호화 작업은 다음 위치에 하드코딩되어 있습니다.

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

Android 9 및 이전 버전에서는 다음 위치에 하드코딩되어 있습니다.

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

예외를 추가하여 특정 디렉터리가 암호화되지 않도록 할 수 있습니다. 이러한 종류의 수정이 이루어지면 기기 제조업체는 암호화되지 않은 디렉터리를 사용해야 하는 애플리케이션에만 액세스를 부여하는 SELinux 정책을 포함해야 합니다. 그러면 신뢰할 수 없는 모든 애플리케이션이 제외됩니다.

이와 관련하여 알려진 허용 가능한 유일한 사용 사례는 레거시 OTA 기능을 지원합니다.

시스템 애플리케이션에서 직접 부팅 지원

애플리케이션이 직접 부팅을 인식하도록 만들기

시스템 앱의 빠른 이전을 용이하게 하려면 애플리케이션 수준에서 두 가지의 새로운 속성을 설정하면 됩니다. defaultToDeviceProtectedStorage 속성은 시스템 앱에만 사용할 수 있으며 directBootAware 속성은 모든 앱에 사용할 수 있습니다.

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

애플리케이션 수준의 directBootAware 속성은 앱의 모든 구성요소를 암호화 인식으로 표시하는 약어입니다.

defaultToDeviceProtectedStorage 속성은 기본 앱 저장소 위치를 리디렉션하여 CE 저장소 대신 DE 저장소를 가리킵니다. 이 플래그를 사용하는 시스템 앱은 기본 위치에 저장된 모든 데이터를 신중하게 감사하여 민감한 데이터의 경로로 CE 저장소를 사용하도록 변경해야 합니다. 이 옵션을 사용하는 기기 제조업체는 저장하는 데이터를 신중히 검사하여 개인정보가 포함되지 않도록 해야 합니다.

이 모드에서 실행 중인 경우에는 필요한 경우 다음과 같은 시스템 API를 사용하여 CE 저장소에 의해 지원되는 컨텍스트를 명시적으로 관리할 수 있습니다. 이는 기기로 보호되는 API와 동일합니다.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

멀티 사용자 지원

멀티 사용자 환경의 각 사용자는 별도의 암호화 키를 받습니다. 모든 사용자는 DE 및 CE 키, 이렇게 두 개의 키를 받습니다. 사용자 0은 특수 사용자이므로 먼저 기기에 로그인해야 합니다. 이는 기기 관리 용도와 관련이 있습니다.

암호화 인식 애플리케이션은 이러한 방식으로 모든 사용자와 상호작용합니다. INTERACT_ACROSS_USERSINTERACT_ACROSS_USERS_FULL은 애플리케이션이 기기의 모든 사용자에 대해 기능할 수 있도록 해줍니다. 하지만 이러한 앱은 이미 잠금 해제된 사용자와 관련하여 CE로 암호화된 디렉터리에만 액세스할 수 있습니다.

애플리케이션은 DE 영역 전체에 걸쳐 자유롭게 상호작용할 수 있지만 사용자 한 명이 잠금 해제되었다고 해서 기기의 모든 사용자가 잠금 해제되는 것은 아닙니다. 애플리케이션은 이러한 영역에 액세스하려고 하기 전에 이 상태를 확인해야 합니다.

각 직장 프로필 사용자 ID에도 DE 및 CE라는 두 개의 키가 주어집니다. 직장 보안 확인이 충족되면 프로필 사용자가 잠금 해제되며 TEE의 Keymaster는 프로필의 TEE 키를 제공할 수 있습니다.

업데이트 처리

복구 파티션은 사용자 데이터 파티션의 DE 보호 저장소에 액세스할 수 없습니다. FBE를 구현하는 기기는 A/B 시스템 업데이트를 사용하여 OTA를 지원하는 것이 좋습니다. OTA는 일반적인 작업 중에 적용할 수 있습니다. 따라서 복구 시 암호화된 드라이브의 데이터에 액세스할 필요가 없습니다.

복구 시 userdata 파티션의 OTA 파일에 액세스해야 하는 레거시 OTA 솔루션을 사용할 때에는 다음을 실행합니다.

  1. userdata 파티션에서 최상위 수준 디렉터리(예: misc_ne)를 생성합니다.
  2. 이 최상위 디렉터리를 암호화되지 않도록 구성합니다(디렉터리 제외 참고).
  3. 최상위 수준 디렉터리 내에 OTA 패키지를 보관할 디렉터리를 생성합니다.
  4. SELinux 규칙 및 파일 컨텍스트를 추가하여 이 디렉터리와 콘텐츠에 대한 액세스를 제어합니다. OTA 업데이트를 수신하는 프로세스나 애플리케이션만 이 디렉터리를 읽고 쓸 수 있으며, 다른 모든 애플리케이션과 프로세스는 이 디렉터리에 액세스할 수 없어야 합니다.

유효성 검사

구현 된 기능 버전이 의도 한대로 작동하도록하려면 먼저 DirectbootHostTestEncryptionTest와 같은 여러 CTS 암호화 테스트를 실행합니다.

기기에서 Android 11 이상을 실행 중이면 vts_kernel_encryption_test도 실행하세요.

atest vts_kernel_encryption_test

또는:

vts-tradefed run vts -m vts_kernel_encryption_test

기기 제조업체는 다음과 같은 수동 테스트를 수행할 수도 있습니다. FBE가 사용 설정된 기기에서 다음을 실행합니다.

  • ro.crypto.state가 있는지 확인합니다.
    • ro.crypto.state가 암호화되어 있는지 확인합니다.
  • ro.crypto.type이 있는지 확인합니다.
    • ro.crypto.typefile로 설정되어 있는지 확인합니다.

또한 테스터는 기본 사용자에 설정된 잠금 화면으로 userdebug 인스턴스를 부팅할 수 있습니다. 그러면 adb가 기기에 포함되고 su를 사용하여 루트가 됩니다. /data/data에 암호화된 파일 이름이 포함되어 있는지 확인하세요. 포함되어 있지 않다면 문제가 있는 것입니다.

또한 기기 제조업체는 기기 또는 커널에서 fscrypt용 업스트림 Linux 테스트를 실행하는지 알아보는 것이 좋습니다. 이러한 테스트는 xfstests 파일 시스템 테스트 제품군의 일부입니다. 하지만 이와 같은 업스트림 테스트는 Android에서 공식적으로 지원하지 않습니다.

AOSP 구현 세부정보

이 섹션에서는 AOSP 구현, 그리고 파일 기반 암호화의 원리에 대해 자세히 설명합니다. 기기 제조업체가 FBE 및 직접 부팅을 기기에서 사용하기 위해 여기서 내용을 변경할 필요는 없습니다.

fscrypt 암호화

AOSP 구현은 ext4 및 f2fs에서 지원하는 'fscrypt' 암호화를 커널에 사용하며, 일반적인 구성은 아래와 같습니다.

  • XTS 모드에서 AES-256으로 파일 콘텐츠 암호화
  • CBC-CTS 모드에서 AES-256으로 파일 이름 암호화

Adiantum 암호화도 지원됩니다. Adiantum 암호화를 사용 설정하면 파일 콘텐츠와 파일 이름 모두 Adiantum으로 암호화됩니다.

fscrypt는 버전 1과 버전 2, 두 가지 버전의 암호화 정책을 지원합니다. 버전 1은 지원 중단되었으며, Android 11 및 이후 버전으로 출시되는 기기의 CDD 요구사항은 버전 2하고만 호환됩니다. 버전 2 암호화 정책은 HKDF-SHA512를 사용하여 사용자 공간에서 제공된 키에서 실제 암호화 키를 가져옵니다.

fscrypt에 관한 자세한 내용은 업스트림 커널 문서를 참고하세요.

스토리지 클래스

다음 표에는 FBE 키와 각 키가 보호하는 디렉터리가 나열되어 있습니다.

스토리지 클래스 설명 디렉터리
시스템 DE 특정 사용자와 연결되지 않은 기기 암호화 데이터 /data/system, /data/app을 비롯한 /data의 여러 하위 디렉터리
부팅당 재부팅 후에 유지될 필요가 없는 임시 시스템 파일 /data/per_boot
사용자 CE(내부) 사용자별 사용자 인증 정보가 암호화된 내부 저장소의 데이터
  • /data/data(/data/user/0의 별칭)
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
사용자 DE(내부) 사용자별 기기가 암호화된 내부 저장소의 데이터
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
사용자 CE(어답터블) 사용자별 사용자 인증 정보가 암호화된 어답터블 스토리지의 데이터
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
사용자 DE(어답터블) 사용자별 기기가 암호화된 어답터블 저장소의 데이터
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

키 스토리지 및 보호

모든 FBE 키는 vold에 의해 관리되며 디스크에 암호화된 상태로 저장됩니다. 단, 아예 저장되지 않는 부팅당 키는 예외입니다. 다음 표에는 여러 FBE 키가 저장되는 위치가 나열되어 있습니다.

키 유형 키 위치 키 위치의 스토리지 클래스
시스템 DE 키 /data/unencrypted 암호화되지 않음
사용자 CE(내부) 키 /data/misc/vold/user_keys/ce/${user_id} 시스템 DE
사용자 DE(내부) 키 /data/misc/vold/user_keys/de/${user_id} 시스템 DE
사용자 CE(어답터블) 키 /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} 사용자 CE(내부)
사용자 DE(어답터블) 키 /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} 사용자 DE(내부)

위 표에서 볼 수 있듯이 대부분의 FBE 키는 다른 FBE 키로 암호화된 디렉터리에 저장됩니다. 키는 이 키를 포함하는 스토리지 클래스가 잠금 해제되기 전까지는 잠금 해제될 수 없습니다.

vold는 모든 FBE 키에 암호화 레이어도 적용합니다. 내부 저장소의 CE 키를 제외한 모든 키는 TEE 외부로 노출되지 않는 자체 키 저장소 키를 사용하여 AES-256-GCM으로 암호화됩니다. 따라서 신뢰할 수 있는 운영체제가 부팅된 경우가 아니라면 FBE 키가 잠금 해제되지 않습니다. 신뢰할 수 있는 운영체제는 자체 검사 부팅에 의해 시행됩니다. Keymaster가 롤백 방지를 지원하는 기기에서 FBE 키를 안전하게 삭제할 수 있도록 키 저장소 키에 롤백 방지도 요구됩니다. 롤백 방지를 사용할 수 없는 경우에는 최선의 대안으로 secdiscardable 파일에 키와 함께 저장된 임의의 16,384바이트의 SHA-512 해시가 키 저장소 키의 애플리케이션 ID 태그로 사용됩니다. FBE 키를 복구하려면 이 바이트를 모두 복구해야 합니다.

내부 저장소의 CE 키에는 사용자의 잠금 화면 지식 계수(LSKF)(PIN, 패턴 또는 비밀번호), 보안 비밀번호 재설정 토큰 또는 재부팅 시 다시 시작 작업을 위한 클라이언트 측 키와 서버 측 키 둘 다를 모르면 잠금 해제할 수 없도록 하는 더 강력한 수준의 보호가 적용됩니다. 비밀번호 재설정 토큰은 직장 프로필완전 관리형 기기용으로만 만들 수 있습니다.

이를 위해 vold는 사용자의 합성 비밀번호에서 파생된 AES-256-GCM 키를 사용하여 내부 저장소의 각 CE 키를 암호화합니다. 합성 비밀번호는 각 사용자별로 무작위로 생성되는 변경 불가능한 높은 엔트로피의 암호화 보안 비밀입니다. system_serverLockSettingsService는 합성 비밀번호와 비밀번호가 보호되는 방식을 관리합니다.

LockSettingsService는 LSKF를 사용하여 합성 비밀번호를 보호하기 위해 먼저 LSKF를 scrypt를 통해 전달하여 늘립니다. 이때 시간은 약 25밀리초, 메모리 사용량은 약 2MiB로 설정합니다. LSKF는 보통 짧기 때문에 일반적으로 이 단계는 그다지 강력한 보안을 제공하지 않습니다. 보안의 기본 레이어는 아래에서 설명하는 보안 요소(SE) 또는 TEE에서 시행하는 비율 제한입니다.

기기에 보안 요소(SE)가 있으면 LockSettingsService는 늘어난 LSKF를 위버 HAL을 사용하여 SE에 저장된 높은 엔트로피의 임의 보안 비밀에 매핑합니다. 그런 다음 LockSettingsService는 합성 비밀번호를 두 번 암호화합니다. 먼저 늘어난 LSKF와 위버 보안 비밀에서 파생된 소프트웨어 키를 사용하여 암호화하고, 인증이 결합되지 않은 키 저장소 키를 사용하여 암호화합니다. 그 결과 SE에 의해 시행되는 LSKF 추측 비율 제한이 이루어집니다.

기기에 SE가 없으면 LockSettingsService는 늘어난 LSKF를 게이트키퍼 비밀번호로 사용합니다. 그런 다음 LockSettingsService는 합성 비밀번호를 두 번 암호화합니다. 먼저 늘어난 LSKF와 secdiscardable 파일 해시에서 파생된 소프트웨어 키를 사용하여 암호화하고, 게이트키퍼 등록에 인증이 결합된 키 저장소 키를 사용하여 암호화합니다. 그 결과 TEE에 의해 시행되는 LSKF 추측 비율 제한이 이루어집니다.

LSKF가 변경되면 LockSettingsService는 합성 비밀번호와 이전 LSKF의 결합과 관련된 모든 정보를 삭제합니다. 그 결과 위버 또는 롤백 방지 키 저장소 키를 지원하는 기기에서 이전 결합의 안전한 삭제가 보장됩니다. 따라서 여기에서 설명하는 보호 기능은 사용자에게 LSKF가 없는 경우에도 적용됩니다.