臉孔驗證 HIDL

總覽

臉部驗證功能可讓使用者只要看著裝置正面,就能解鎖裝置。Android 10 新增支援新的臉部驗證堆疊,可安全地處理攝影機畫面,在支援的硬體上進行臉部驗證時,確保安全和隱私。Android 10 也提供簡單的方法,讓符合安全規定的實作項目啟用應用程式整合功能,以進行線上銀行或其他服務等交易。

Android 臉部驗證堆疊是 Android 10 的新實作項目。新實作項目導入了 IBiometricsFace.halIBiometricsFaceClientCallback.haltypes.hal 介面。

建築

BiometricPrompt API 包含所有生物辨識驗證方式,包括臉部、指紋和虹膜。Face HAL 會與下列元件互動。

生物辨識堆疊

圖 1. 生物辨識堆疊。

FaceManager

FaceManager 是維護與 FaceService 連線的私有介面。Keyguard 會使用這個方法,透過自訂 UI 存取臉孔驗證功能。應用程式無法存取 FaceManager,必須改用 BiometricPrompt

FaceService

這個架構實作項目會管理臉部驗證硬體的存取權。其中包含基本註冊和驗證狀態機器,以及各種其他輔助程式 (例如列舉)。基於穩定性和安全性考量,這個程序不允許執行任何供應商程式碼。所有供應商程式碼都透過 Face 1.0 HIDL 介面存取。

面臨

這是 Linux 可執行檔,可實作 FaceService 使用的 Face 1.0 HIDL 介面。它會將自己註冊為 IBiometricsFace@1.0,以便 FaceService 找到它。

實作

Face HIDL

如要實作 Face HIDL,您必須在供應商專屬程式庫中實作 IBiometricsFace.hal 的所有方法

錯誤訊息

錯誤訊息會透過回呼傳送,並在傳送後將狀態機器返回「閒置」狀態。大多數訊息都有對應的使用者可見字串,可向使用者說明錯誤,但並非所有錯誤都有這類字串。如要進一步瞭解錯誤訊息,請參閱types.hal。所有錯誤訊息都代表終端狀態,也就是說,架構會假設 HAL 在傳送錯誤訊息後返回閒置狀態。

獲取訊息

系統會在註冊或驗證期間傳送獲取訊息,引導使用者順利完成註冊或驗證。每個序數都與 FaceAuthenticationManager.java 檔案中的訊息相關聯。只要提供對應的說明字串,即可新增廠商專屬訊息。獲取訊息本身並非終端狀態;HAL 應視需要傳送多個這類訊息,以完成目前的註冊或驗證。如果擷取訊息導致終端機進入無法繼續作業的狀態,HAL 應在擷取訊息後傳送錯誤訊息,例如圖片太暗,且持續太暗而無法繼續作業。在這種情況下,多次嘗試後仍無法取得進展,因此傳送 UNABLE_TO_PROCESS 是合理的做法。

硬體

如要讓裝置符合 Android 10 的嚴格生物辨識規定,裝置必須具備安全硬體,確保臉部資料的完整性,以及最終的驗證比較結果。Android 相容性定義說明文件 (CDD) 規定了必要的安全等級和可接受的欺騙接受率 (SAR)。安全處理和辨識程序必須在受信任的執行環境 (TEE) 中執行。此外,還需要安全的攝影機硬體,才能防止臉部驗證遭到注入攻擊。舉例來說,圖片資料的相關記憶體頁面可能具有特殊權限,並標示為唯讀,因此只有攝影機硬體可以更新這些頁面。理想情況下,除了 TEE 和硬體,任何程序都不應有存取權。

由於臉部驗證硬體差異極大,因此視特定裝置架構而定,必須開發專屬硬體驅動程式,才能啟用臉部驗證。因此,faced 沒有參考實作項目。

方法

下列方法皆為非同步,且必須立即傳回架構。否則系統會變慢,且可能發生 Watchdog 重設。建議您使用多個執行緒的訊息佇列,以免封鎖呼叫端。所有 GET 要求都應盡可能快取資訊,以盡量縮短呼叫端遭到封鎖的時間。

方法 說明
setCallback() FaceService 呼叫,將所有訊息回傳至自身。
setActiveUser() 設定有效使用者,後續所有 HAL 作業都會套用至該使用者。 在再次呼叫這個方法之前,系統一律會針對這個使用者進行驗證。
revokeChallenge() 透過使 generateChallenge() 產生的驗證失效,完成安全交易。
enroll() 註冊使用者臉部。
cancel() 取消目前作業 (例如註冊、驗證、移除或列舉),並將 faced 傳回閒置狀態。
enumerate() 列舉與活躍使用者相關聯的所有臉部範本。
remove() 移除與現用使用者相關聯的臉部範本或所有臉部範本。
authenticate() 驗證活躍使用者。
userActivity() 只有在 HAL 處於驗證或待命狀態時,才應使用這個方法。如果 HAL 不處於上述任一狀態,使用這個方法會傳回 OPERATION_NOT_SUPPORTED。如果 HAL 正在進行驗證,呼叫這個方法可能會延長系統尋找臉部所需的時間。
resetLockout() 如果拒絕太多張臉孔,faced必須進入鎖定狀態 (LOCKOUTLOCKOUT_PERMANENT)。進入鎖定狀態時,必須將剩餘時間傳送至架構,以便向使用者顯示。與 setFeature() 相同,這個方法需要有效的硬體驗證權杖 (HAT),才能安全地重設內部狀態。僅為目前使用者重設鎖定狀態。

其餘三種方法都是同步,應盡量縮短封鎖時間,以免架構停滯。

方法 說明
generateChallenge() 產生不重複且安全加密的隨機權杖,用於表示安全交易的開始。
setFeature() 為目前使用者啟用或停用功能。基於安全考量,這需要 HAT,才能根據上述驗證檢查使用者的 PIN 碼/解鎖圖案/密碼
getFeature() 擷取功能的目前啟用狀態,如預設值或上述對 setFeature() 的呼叫所指定。如果臉部 ID 無效,實作項目必須傳回 ILLEGAL_ARGUMENT
getAuthenticatorId() 傳回與目前臉部集合相關聯的 ID。 每當新增臉孔時,這個 ID 必須變更

狀態圖

架構預期 faced 會遵循下方的狀態圖。

狀態圖

圖 2. 臉部驗證狀態流程。