Android에는 기기를 잠금 해제하고 암호화 키에 대한 액세스를 제한하는 데 사용되는 사용자 인증자라는 개념이 있습니다. 여기에는 다음 구성요소가 포함됩니다.
- 암호화 키 저장소 및 서비스 제공업체: 암호화 키를 저장하고 이러한 키 외에 표준 암호법 루틴을 제공합니다. Android에서는 암호화 서비스를 위한 하드웨어 지원 키 저장소 및 KeyMint (이전 명칭: Keymaster)를 지원합니다. 여기에는 StrongBox와 같은 TTE(신뢰할 수 있는 실행 환경) 또는 SE (보안 요소)가 포함될 수 있는 키 저장소의 하드웨어 지원 암호화도 포함됩니다.
- 사용자 인증자: 사용자의 존재 및 인증 성공을
증명합니다. Android에서는 PIN/패턴/비밀번호 인증을 위한 게이트키퍼와 지문 인증을 위한 지문을 지원합니다. Android 9 이상이 기본으로 적용된 기기는
BiometricPrompt
를 지문 및 추가 생체 인식을 위한 단일 통합 지점으로 사용할 수 있습니다. 이러한 구성요소는 인증 채널을 통해 인증 상태를 키 저장소 서비스와 통신합니다. 프레임워크 수준의 Android 키 저장소 시스템도 키 저장소 서비스에서 지원됩니다.
이러한 각 구성요소는 공급업체별이지만 공급업체 구현은 하드웨어 추상화 계층 (HAL) 인터페이스 사양을 충족하고 해당 공급업체 테스트 모음 (VTS) 테스트를 통과해야 합니다.
공급업체 구현도 일반적으로 공급업체별 통신 메커니즘으로 연결된 두 부분으로 나뉩니다.
- HAL 서비스는 Android 시스템 프로세스로 실행되며 Android 시스템에서 바인더 요청을 수신합니다.
- 신뢰할 수 있는 애플리케이션 (TA)은 보안 환경에서 실행되어 실제 보안 작업을 실행합니다.
등록
초기화 이후에 기기가 처음 부팅되면 모든 인증이 사용자의 인증 정보 등록을 수신할 준비를 마칩니다. 사용자는 처음에 게이트키퍼 (또는 Weaver, 사용 가능한 경우)에 PIN, 패턴 또는 비밀번호를 등록해야 합니다. 이 최초 등록 시 64비트 사용자 보안 식별자(SID)가 무작위로 생성됩니다. 사용자 보안 식별자는 사용자 식별자 및 사용자 암호화 자료의 바인딩 토큰으로 사용됩니다. 이 사용자 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가 포함된 AuthToken을 내보냅니다(공유 HMAC 키로 서명됨). - 지문 인증의 경우
fingerprintd
는 지문 이벤트를 수신 대기하고 지문 HAL을 통해 데이터를 TEE의 지문 TA로 전송합니다. TEE의 인증이 성공하면 지문 TA가 AuthToken HMAC 키로 서명된 AuthToken을 내보냅니다. - 다른 생체 인식 인증의 경우 적절한 생체 인식 데몬이 생체 인식 이벤트를 수신 대기하고 이를 적절한 생체 인식 HAL 서비스 및 TA로 전송합니다.
- PIN/패턴/비밀번호 인증의 경우
- 데몬이 서명된 AuthToken을 수신하여 키 저장소 서비스의 바인더 인터페이스 확장 프로그램을 통해 키 저장소 서비스로 전달합니다.
gatekeeperd
는 기기가 다시 잠금 처리되거나 기기 비밀번호가 변경될 때 키 저장소 서비스에도 알립니다. - 키 저장소 서비스는 AuthToken을 KeyMint에 전달하고 게이트키퍼 및 지원되는 생체 인식 TEE 구성요소와 공유된 키를 사용하여 확인합니다. KeyMint는 토큰의 타임스탬프를 마지막 인증 시간으로 신뢰하고 키 출시 결정 (앱에서 키를 사용하도록 허용)을 타임스탬프에 기반합니다.
인증 흐름에는 보안 환경의 TA 간 직접 통신이 필요하지 않습니다. AuthToken은 인증자 TA에서 Android의 keystore2
서비스로 흐르고, 이 서비스는 다시 KeyMint TA로 전달합니다.
또한 시스템에서 사용 가능한 AuthToken에 관한 정보가 있으므로 keystore2
서비스에서 실패가 확실한 요청을 빠르게 거부하여 비용이 많이 드는 IPC를 TEE에 저장하지 않아도 됩니다.
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에 저장하지 않아도 됩니다.