Android 使用使用者驗證門控加密金鑰的概念,需要以下元件:
- 加密金鑰儲存和服務提供者。儲存加密金鑰並在這些金鑰之上提供標準加密例程。 Android 支援用於加密服務的硬體支援的 Keystore和 Keymaster,包括用於金鑰儲存的硬體支援的加密,其中可能包括可信任執行環境 (TEE) 或安全元件 (SE),例如 Strongbox。
- 用戶驗證器。證明使用者的存在和/或成功的身份驗證。 Android 支援用於 PIN/圖案/密碼驗證的Gatekeeper和用於指紋身份驗證的Fingerprint 。搭載 Android 9 及更高版本的裝置可以使用
BiometricPrompt
作為指紋和其他生物辨識技術的單一整合點。這些元件透過經過驗證的通道與金鑰庫服務傳達其身份驗證狀態。 (框架層級的Android Keystore 系統也由 keystore 服務支援。)
Gatekeeper、指紋和生物辨識元件與金鑰庫和其他元件配合使用,以支援使用硬體支援的驗證令牌(AuthToken)。
註冊
恢復出廠設定後首次啟動裝置時,所有驗證器都準備好接收來自使用者的憑證註冊。使用者必須先向 Gatekeeper 註冊 PIN/圖案/密碼。此初始註冊會建立一個隨機產生的 64 位元使用者安全性識別碼 (SID),該識別碼充當使用者的識別碼以及使用者加密資料的綁定令牌。該用戶 SID 以加密方式與用戶密碼綁定;成功對 Gatekeeper 進行驗證會產生包含該密碼的使用者 SID 的 AuthToken。
想要更改憑證的使用者必須出示現有憑證。如果現有憑證驗證成功,與現有憑證關聯的使用者 SID 將轉移到新憑證,使用戶能夠在變更憑證後繼續存取金鑰。如果使用者未提供現有憑證,則會使用完全隨機的使用者 SID 註冊新憑證。使用者可以存取設備,但在舊用戶 SID 下建立的金鑰將永久遺失。這稱為不受信任的註冊。
正常情況下,Android 框架不允許不受信任的註冊,因此大多數用戶不會看到此功能。但是,設備管理員或攻擊者強制重設密碼可能會導致這種情況發生。
驗證
使用者設定憑證並收到使用者 SID 後,即可開始身分驗證,身分驗證從使用者提供 PIN、圖案、密碼或指紋時開始。所有 TEE 元件共用一個金鑰,用於驗證彼此的訊息。
![認證流程](https://source.android.google.cn/static/docs/security/images/authentication-flow.png?authuser=8&hl=zh-tw)
- 使用者提供身份驗證方法,相關服務向相關守護程式發出請求。
- 對於 PIN、圖案或密碼,
LockSettingsService
向gatekeeperd
發出請求。 - 基於生物辨識的身份驗證流程取決於 Android 版本。在運行 Android 8.x 及更低版本的裝置上,
FingerprintService
會向fingerprintd
發出請求。在運行 Android 9 及更高版本的裝置上,BiometricPrompt
使用適當的生物辨識管理器類別(例如FingerprintManager
或FaceManager
)向適當的Biometric Manager
程式(例如,fingerprintd
的 Fingerprintd 或faced
的 Face)發出請求。無論版本如何,生物識別身份驗證都會在發送請求後非同步發生。
- 對於 PIN、圖案或密碼,
- 守護程式將資料傳送到其對應方,後者產生 AuthToken:
- 對於 PIN/模式/密碼驗證,
gatekeeperd
將 PIN、模式或密碼雜湊傳送到 TEE 中的 Gatekeeper。如果 TEE 中的驗證成功,TEE 中的 Gatekeeper 會向 Android 作業系統中的對應方傳送包含對應使用者 SID(使用 AuthToken HMAC 金鑰簽署)的 AuthToken。 - 對於指紋認證,
fingerprintd
監聽指紋事件並將資料傳送到 TEE 中的 Fingerprint。如果 TEE 中的驗證成功,TEE 中的 Fingerprint 會將 AuthToken(使用 AuthToken HMAC 金鑰簽署)傳送到 Android 作業系統中的對應方。 - 對於其他生物辨識身份驗證,適當的生物辨識守護程序會偵聽生物辨識事件並將其傳送到適當的生物辨識 TEE 組件。
- 對於 PIN/模式/密碼驗證,
- 守護程式接收簽署的 AuthToken 並透過金鑰庫服務的 Binder 介面的擴充將其傳遞給金鑰庫服務。 (當裝置重新鎖定和裝置密碼變更時,
gatekeeperd
也會通知金鑰庫服務。) - 金鑰庫服務將 AuthToken 傳遞給 Keymaster,並使用與 Gatekeeper 和支援的生物識別 TEE 元件共享的金鑰來驗證它們。 Keymaster 信任令牌中的時間戳記作為最後一次驗證時間,並根據時間戳記做出金鑰發布決策(以允許應用程式使用金鑰)。
AuthToken 格式
為了確保跨語言和元件的令牌共享和相容性, hw_auth_token.h
中描述了 AuthToken 格式。該格式是具有固定大小欄位的簡單序列化協定。
場地 | 類型 | 必需的 | 描述 |
---|---|---|---|
AuthToken版本 | 1位元組 | 是的 | 以下所有欄位的群組標籤。 |
挑戰 | 64 位元無符號整數 | 不 | 用於防止重播攻擊的隨機整數。通常是請求的加密操作的 ID。目前用於交易指紋授權。如果存在,則 AuthToken 僅對包含相同質詢的加密操作有效。 |
用戶SID | 64 位元無符號整數 | 是的 | 非重複使用者識別碼以加密方式與與裝置驗證相關的所有金鑰綁定。詳情請參閱網守。 |
身份驗證器 ID (ASID) | 網路順序的 64 位元無符號整數 | 不 | 用於綁定到特定身份驗證器策略的識別碼。所有驗證器都有自己的 ASID 值,可以根據自己的要求進行變更。 |
認證器類型 | 網路順序的 32 位元無符號整數 | 是的 |
|
時間戳 | 網路順序的 64 位元無符號整數 | 是的 | 自從最近一次系統啟動以來的時間(以毫秒為單位)。 |
AuthToken HMAC (SHA-256) | 256 位元 blob | 是的 | 除 HMAC 欄位以外的所有欄位的金鑰 SHA-256 MAC。 |
設備啟動流程
每次啟動設備時,必須產生 AuthToken HMAC 金鑰並與所有 TEE 元件(Gatekeeper、Keymaster 和支援的生物辨識 Trustlet)共用。因此,為了增強針對重播攻擊的保護,每次裝置重新啟動時都必須隨機產生 HMAC 金鑰。
與所有元件共用此 HMAC 金鑰的協定是依賴平台的實作功能。絕不能在 TEE 之外提供金鑰。如果TEE作業系統缺乏內部進程間通訊(IPC)機制,則需要透過不可信作業系統傳輸數據,則必須透過安全金鑰交換協定來完成傳輸。
與 Android 一起運行的Trusty作業系統是 TEE 的一個範例,但也可以使用其他 TEE。 Trusty 使用內部 IPC 系統在 Keymaster 和 Gatekeeper 或適當的生物辨識 trustlet 之間直接通訊。 HMAC 金鑰僅保存在 Keymaster 中; Fingerprint 和 Gatekeeper 每次使用時都會向 Keymaster 請求金鑰,並且不會保留或快取該值。
由於一些 TEE 缺乏 IPC 基礎設施,TEE 中的 applet 之間不會發生通訊。這也允許金鑰庫服務快速拒絕注定會失敗的請求,因為它了解系統中的身份驗證表,從而將可能成本高昂的 IPC 節省到 TEE 中。