Android에는 기기를 잠금 해제하고 암호화 키에 대한 액세스를 제한하는 데 사용되는 사용자 인증자 개념이 있습니다. 여기에는 다음 구성요소가 포함됩니다.
- 암호화 키 저장소 및 서비스 제공업체: 암호화 키를 저장하고 이러한 키 외에 표준 암호법 루틴을 제공합니다. Android에서는 암호화 서비스를 위한 하드웨어 기반의 키 저장소 및 KeyMint (이전의 Keymaster)를 지원합니다. 여기에는 StrongBox와 같은 TEE(신뢰할 수 있는 실행 환경) 또는 SE (보안 요소)가 포함될 수 있는 키 저장소의 하드웨어 기반의 암호화도 포함됩니다.
- 사용자 인증자: 사용자의 존재 및 인증 성공을
증명합니다. Android에서는 PIN/패턴/비밀번호 인증을 위한 게이트키퍼와 지문 인증을 위한 지문을 지원합니다. Android 9 이상이 기본으로 적용된 기기는
BiometricPrompt를 지문 및 추가 생체 인식을 위한 단일 통합 지점으로 사용할 수 있습니다. 이러한 구성요소는 인증 채널을 통해 인증 상태를 키 저장소 서비스와 통신합니다. 프레임워크 수준의 Android 키 저장소 시스템도 키 저장소 서비스에서 지원됩니다.
이러한 각 구성요소는 공급업체별이지만 공급업체 구현은 하드웨어 추상화 계층 (HAL) 인터페이스 사양을 충족하고 상응하는 공급업체 테스트 모음 (VTS) 테스트를 통과해야 합니다.
공급업체 구현은 일반적으로 공급업체별 통신 메커니즘으로 연결된 두 부분으로도 나뉩니다.
- HAL 서비스 는 Android 시스템 프로세스로 실행되며 Android 시스템에서 바인더 요청을 수신합니다.
- 신뢰할 수 있는 애플리케이션 (TA) 은 보안 환경에서 실행되며 실제 보안 작업을 실행합니다.
등록
초기화 이후에 기기가 처음 부팅되면 모든 인증이 사용자의 인증 정보 등록을 수신할 준비를 마칩니다. 사용자는 처음에 게이트키퍼 (또는 사용 가능한 경우 Weaver)에 PIN, 패턴 또는 비밀번호를 등록해야 합니다. 최초 등록 시 64비트 사용자 SID(보안 식별자)가 무작위로 생성됩니다. 사용자 SID는 사용자 ID, 그리고 사용자의 암호화 자료와 관련된 귀속 토큰으로 기능합니다. 이 사용자 SID는 사용자의 비밀번호에 암호화 방식으로 귀속됩니다. 게이트키퍼 인증에 성공하면 비밀번호의 사용자 SID를 포함하는 AuthToken이 결과물로 생성됩니다.
기존 사용자 인증 정보를 변경하려는 사용자는 해당 사용자 인증 정보를 제시해야 합니다. 기존 사용자 인증 정보가 성공적으로 확인되면 기존 사용자 인증 정보에 연결된 사용자 SID가 새로운 사용자 인증 정보로 전송되어 사용자는 사용자 인증 정보 변경 후에도 계속해서 키에 액세스할 수 있습니다.
경우에 따라 기기 관리자는 기존 사용자 인증 정보를 제시하지 않고 새 사용자 인증 정보를 등록하기 위해 신뢰할 수 없는 등록 을 실행할 수 있습니다. 이렇게 하면 사용자가 기기에 액세스할 수 있지만 기존 사용자 SID로 생성된 키는 영구적으로 손실됩니다.
인증
이 섹션에서는 Android와 보안 환경 모두에서 여러 구성요소 간의 상호작용을 포함하는 일반적인 인증 흐름을 설명합니다. 모든 보안 구성요소는 서로의 메시지를 인증하는 데 사용하는 (부팅당) 비밀 HMAC 키를 공유합니다.
사용자가 사용자 인증 정보를 설정하고 사용자 SID를 할당받은 후에는 인증을 시작할 수 있습니다. 이 과정은 사용자가 PIN, 패턴, 비밀번호, 지문 또는 기타 강력한 생체 인식을 제시하면 시작됩니다.
그림 1. 인증 흐름
- 사용자가 인증 수단을 제공하고 관련 서비스에서
HAL 서비스에 요청을 보냅니다.
- PIN, 패턴 또는 비밀번호의 경우
LockSettingsService에서gatekeeperd에 요청을 보냅니다. - 생체 인식 기반 인증 흐름은 Android 버전에 따라 다릅니다.
Android 8.x 이하를 실행하는 기기에서는
FingerprintService에서fingerprintd에 요청합니다. Android 9 이상을 실행하는 기기에서는FingerprintManager또는FaceManager와 같이 적절한BiometricManager클래스를 사용하여BiometricPrompt에서 적합한 생체 인식 데몬에 요청합니다. 예를 들어 지문의 경우fingerprintd또는 얼굴의 경우faced입니다. 버전과 상관없이 생체 인식 인증은 요청이 전송된 후 비동기식으로 발생합니다.
- PIN, 패턴 또는 비밀번호의 경우
- HAL 서비스는 AuthToken을
생성하는 상응 요소 TA에 데이터를 전송합니다.
- PIN/패턴/비밀번호 인증의 경우
gatekeeperd는 게이트키퍼 HAL 서비스를 통해 PIN, 패턴 또는 비밀번호 해시를 TEE의 게이트키퍼 TA로 전송합니다. TEE의 인증이 성공하면 게이트키퍼 TA는 상응하는 사용자 SID (공유 HMAC 키로 서명됨)가 포함된 AuthToken을 내보냅니다. - 지문 인증의 경우
fingerprintd는 지문 이벤트를 수신 대기하고 지문 HAL을 통해 데이터를 TEE의 지문 TA로 전송합니다. TEE의 인증이 성공하면 지문 TA는 AuthToken (AuthToken HMAC 키로 서명됨)을 내보냅니다. - 다른 생체 인식 인증의 경우 적절한 생체 인식 데몬 이 생체 인식 이벤트를 수신 대기하고 이를 적절한 생체 인식 HAL 서비스 및 TA로 전송합니다.
- PIN/패턴/비밀번호 인증의 경우
- 데몬이 서명된 AuthToken을 수신하여 키 저장소
서비스의 바인더 인터페이스 확장 프로그램을 통해 키 저장소 서비스로 전달합니다.
gatekeeperd는 기기가 다시 잠금 처리되거나 기기 비밀번호가 변경될 때 키 저장소 서비스에도 알립니다. - 키 저장소 서비스는 AuthToken을 KeyMint에 전달하고 게이트키퍼 및 지원되는 생체 인식 TEE 구성요소와 공유된 키를 사용하여 확인합니다. KeyMint는 토큰의 타임스탬프를 마지막 인증 시간으로 신뢰하고 키 출시 결정 (앱에서 키를 사용하도록 허용)을 타임스탬프에 기반합니다.
인증 흐름에는 보안 환경의 TA 간 직접 통신이 필요하지 않습니다. AuthToken은 인증자 TA에서 Android의 keystore2 서비스로 흐르고, 이 서비스는 AuthToken을 KeyMint TA로 전달합니다.
또한 시스템에서 사용 가능한 AuthToken에 관한 정보가 있어서 비용이 많이 드는 IPC를 TEE에 저장하는 keystore2 서비스에서 실패가 확실한 요청을 빠르게 거부할 수 있습니다.
AuthToken 형식
AuthToken의 형식은
HardwareAuthToken.aidl의 AIDL 사양에 나와 있습니다.
기기 부팅 흐름
기기가 부팅될 때마다 AuthToken HMAC 키를 생성하여 모든 TEE 구성요소 (게이트키퍼, KeyMint 및 지원되는 생체 인식 trustlet)와 공유해야 합니다. 따라서 재전송 공격 방지를 강화하려면 기기가 재부팅될 때마다 HMAC 키를 무작위로 생성해야 합니다.
TA가 이 공유 HMAC 키에 액세스하는 일반적인 방법에는 두 가지가 있습니다.
- 공유 비밀번호 계약:
keystore2서비스는 기기 시작 시 다자간 키 계약 프로토콜을 실행하여 참여하는 TA 간에 HMAC 키를 안전하게 파생할 수 있도록 합니다. 하지만 참여하는 TA는 공통의 사전 공유 비밀번호에 액세스할 수 있어야 합니다. - 직접 액세스: 동일한 보안 환경에 있는 TA는 플랫폼에 종속된 내부 프로세스 간 통신 메커니즘 을 사용하여 HMAC 키를 공유할 수 있습니다.
어떤 경우든 HMAC 키는 TEE 외부에서 사용할 수 있도록 해서는 안 됩니다.
Android 옆에서 실행되는 Trusty 운영체제는 TEE의 한 예이지만 다른 TEE를 대신 사용할 수도 있습니다. Trusty는 내부 IPC 시스템을 사용하여 KeyMint 및 게이트키퍼 또는 적절한 생체 인식 trustlet과 직접적으로 통신합니다. HMAC 키는 KeyMint에만 보관됩니다. 지문 및 게이트키퍼는 사용 시마다 KeyMint에서 키를 요청하며 값을 유지하거나 캐시하지 않습니다.
일부 TEE에는 IPC 인프라가 없으므로 TEE의 애플릿 간에 통신이 발생하지 않습니다. 따라서 시스템의 인증 표에 관한 정보가 있어서 비용이 많이 드는 IPC를 TEE에 저장하는 키 저장소 서비스에서 실패가 확실한 요청을 빠르게 거부할 수 있습니다.