Android指紋從入門到"放棄"
一宇立、背景
Android在23(Android M)上新增了對(duì)指紋識(shí)別的硬件支持偏灿,應(yīng)用可以通過調(diào)用系統(tǒng)Api實(shí)現(xiàn)指紋驗(yàn)證相關(guān)功能,相對(duì)于傳統(tǒng)的手勢(shì)懂缕,密碼等驗(yàn)證方式狐榔,指紋驗(yàn)證安全性更高,速度也更快建椰。
二雕欺、業(yè)界方案
1.1、FIDO
FIDO是CFCA提出的一種生物認(rèn)證標(biāo)準(zhǔn)棉姐,通過FIDO sdk屠列、手機(jī)硬件、FIDO后臺(tái)構(gòu)成了一套指紋驗(yàn)證解決方案伞矩,保證指紋驗(yàn)證流程不被篡改笛洛,該方案通過與手機(jī)廠商合作,客戶端側(cè)對(duì)秘鑰的操作均在TEE環(huán)境中乃坤,安全性高撞蜂。FIDO方案不僅需要客戶端集成sdk,應(yīng)用后臺(tái)也需要植入FIDO后臺(tái)sdk侥袜,業(yè)務(wù)流程需要由FIDO客戶端sdk蝌诡、應(yīng)用客戶端、應(yīng)用后臺(tái)枫吧、FIDO后臺(tái)sdk浦旱、FIDO服務(wù)端五方共同完成,較為復(fù)雜九杂。一般針對(duì)指紋支付等安全性級(jí)別較高的場(chǎng)景颁湖。
1.2、TENCENT SOTER
TENCENT SOTER是一種生物認(rèn)證標(biāo)準(zhǔn)例隆,同時(shí)也是騰訊生物認(rèn)證平臺(tái)甥捺。TENCENT SOTER主要著眼于如何安全、高效并簡(jiǎn)單地使用你設(shè)備上的傳感器進(jìn)行鑒權(quán)——最重要镀层,也是目前用到最多的就是指紋傳感器镰禾。TENCENT SOTER與FIDO一樣,會(huì)通過與手機(jī)廠商的合作,客戶端側(cè)相關(guān)秘鑰操作均在TEE環(huán)境中吴侦。TENCENT SOTER采用三級(jí)秘鑰方案屋休,應(yīng)用方后臺(tái)不需要接入sdk,接入相對(duì)簡(jiǎn)單备韧。一般針對(duì)指紋支付等安全性級(jí)別較高的場(chǎng)景劫樟。
1.3、Android Framework
Android系統(tǒng)提供的相關(guān)生物識(shí)別驗(yàn)證接口织堂,應(yīng)用可以通過對(duì)這些接口的調(diào)用實(shí)現(xiàn)Android指紋驗(yàn)證功能叠艳,但安全性較低,容易被攻擊者繞過易阳,若需要使用在支付等安全性級(jí)別較高的場(chǎng)景附较,需要配合額外的安全保護(hù)邏輯),且存在較多的兼容性問題闽烙。
三、Android原生方案
3.1声搁、Api介紹
- Android 在23(Android M)上新增了指紋識(shí)別Api:FingerprintManager黑竞,第三方app可以通過對(duì)該類的開發(fā)與使用,實(shí)現(xiàn)指紋相關(guān)功能疏旨。開發(fā)者通過該Api打開指紋認(rèn)證流程時(shí)很魂,系統(tǒng)僅會(huì)打開設(shè)備的指紋模塊監(jiān)聽,并不會(huì)有UI相關(guān)展示檐涝,需要開發(fā)者根據(jù)自身App要求彈出對(duì)應(yīng)的交互流程遏匆。
- Android在28(Android P)上新增了生物識(shí)別Api:BiometricPrompt,并推薦開發(fā)者使用最新的生物識(shí)別Api替換原來的FingerprintManager谁榜,該Api不僅只針對(duì)指紋幅聘,而是囊括了指紋、人臉窃植、虹膜等生物特征識(shí)別帝蒿,但現(xiàn)階段只開放了指紋相關(guān)功能。開發(fā)者使用該Api進(jìn)行指紋認(rèn)證流程時(shí)巷怜,系統(tǒng)在會(huì)打開設(shè)備的指紋模塊監(jiān)聽的同時(shí)葛超,還會(huì)彈出一個(gè)系統(tǒng)級(jí)的Dialog提示用戶正在進(jìn)行指紋解鎖流程。
FingerprintManager與BiometricPrompt中延塑,指紋驗(yàn)證涉及的調(diào)用接口十分類似绣张,本文就以BiometricPrompt為例
- 判斷當(dāng)前設(shè)備是否可以進(jìn)行生物識(shí)別
BiometricManager : canAuthenticate () (29)
- 設(shè)置彈窗系統(tǒng)彈窗title
BiometricPrompt.Builder(28): setSubtitle (CharSequence subtitle)
- 設(shè)置系統(tǒng)彈窗的取消按鈕
BiometricPrompt.Builder(28): setNegativeButton (CharSequence text, Executor executor,DialogInterface.OnClickListener listener)
- 開啟指紋認(rèn)證流程,開發(fā)者調(diào)用該Api后关带,生物識(shí)別傳感器將打開侥涵,同時(shí)屏幕會(huì)彈出一個(gè)系統(tǒng)級(jí)Dialog提示用戶正在進(jìn)行生物識(shí)別。
BiometricPrompt (28): authenticate (BiometricPrompt.CryptoObject crypto, CancellationSignal cancel, Executor executor, BiometricPrompt.AuthenticationCallback callback)
- crypto 成功進(jìn)行生物驗(yàn)證后將使用該對(duì)象驗(yàn)證本次流程的可靠性
- cancel 可以用于結(jié)束本次驗(yàn)證流程的對(duì)象
- executor 本次驗(yàn)證流程的執(zhí)行者(線程相關(guān))
- callback 用于接收本次驗(yàn)證流程結(jié)果的回調(diào)
- 指紋驗(yàn)證流程出現(xiàn)不可重試的錯(cuò)誤時(shí)(如驗(yàn)證5次不通過),系統(tǒng)會(huì)中止指紋驗(yàn)證流程独令,并在一定時(shí)間內(nèi)不可再調(diào)起端朵。
BiometricPrompt.AuthenticationCallback(28): onAuthenticationError(int errorCode, CharSequence errString)
- errorCode 錯(cuò)誤碼
- errString 錯(cuò)誤信息
- 系統(tǒng)識(shí)別出指紋,但該指紋未匹配指紋庫中指紋
BiometricPrompt.AuthenticationCallback(28): onAuthenticationFailed()
- 指紋驗(yàn)證流程出現(xiàn)可重試的錯(cuò)誤時(shí)(如手指滑動(dòng)過快)
BiometricPrompt.AuthenticationCallback(28): onAuthenticationHelp(int helpCode, CharSequence helpString)
- helpCode 錯(cuò)誤碼
- helpString 錯(cuò)誤信息
- 指紋驗(yàn)證成功時(shí)調(diào)用
BiometricPrompt.AuthenticationCallback(28): onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result)
- result 包含authenticate方法中的crypto等對(duì)象
3.2燃箭、版本兼容
- Api23-27:所有功能實(shí)現(xiàn)都使用FingerprintManager冲呢,彈窗由開發(fā)者自定義,非系統(tǒng)彈窗
- Api28:判斷當(dāng)前設(shè)備是否可以進(jìn)行指紋識(shí)別招狸,需要使用FingerprintManager敬拓;進(jìn)行指紋驗(yàn)證流程,需要使用BiometricPrompt
- Api29+:判斷當(dāng)前設(shè)備是否可以進(jìn)行指紋識(shí)別裙戏,需要使用BiometricManager乘凸;進(jìn)行指紋驗(yàn)證流程,需要使用BiometricPrompt
- 也可以使用androidx.biometric包累榜,在大于Api23的所有的Android版本都使用同一套接口营勤,但需要解決將support包全部轉(zhuǎn)為androidx包等一系列問題。
3.3壹罚、存在問題
3.3.1葛作、UI兼容性問題(針對(duì)BiometricPrompt)
由于FingerprintManager是開發(fā)方自定義UI,因此不存在UI兼容性問題猖凛。BiometricPrompt使用的是系統(tǒng)彈窗赂蠢,開發(fā)者不可以自定義彈窗樣式,僅可以設(shè)置彈窗上的相關(guān)文案及按鈕點(diǎn)擊事件辨泳。因此不同廠商對(duì)系統(tǒng)Dialog樣式的不同實(shí)現(xiàn)虱岂,會(huì)導(dǎo)致指紋驗(yàn)證流程中出現(xiàn)不同的交互。
華為mate20 Android29(屏下指紋)
小米Mix2s Android28
三星Galaxy S8+ Android28
OPPO R15X Android28
3.3.2菠红、功能性問題
- 1第岖、在OPPO R15X上(Android28),BiometricDialog彈出后试溯,點(diǎn)擊取消按鈕的點(diǎn)擊事件沒有分發(fā)給第三方App绍傲。
- 2、原生系統(tǒng)耍共,當(dāng)BiometricDialog彈出后烫饼,按下Menu/HOME鍵,指紋驗(yàn)證申請(qǐng)已經(jīng)取消试读,但是彈框BiometricDialog無法消失杠纵。
- 3、原生系統(tǒng)钩骇,若操作不當(dāng)比藻,存在在鎖屏狀態(tài)下彈出Dialog導(dǎo)致無法解鎖铝量,用戶無法進(jìn)入Launcher進(jìn)行UI交互的風(fēng)險(xiǎn)。出現(xiàn)這種“意外” 的情況是银亲,比如:UI處在進(jìn)入申請(qǐng)BiometricPrompt生物識(shí)別彈框上下文慢叨,由于網(wǎng)絡(luò)/apk性能等種種原因,并未立馬申請(qǐng)彈出Dialog务蝠,突然遇到Power熄屏拍谐,或者亮屏超時(shí),立馬按下Power點(diǎn)亮屏幕馏段。此時(shí)三方應(yīng)用處在onPaused狀態(tài)轩拨,但是異步發(fā)起生物識(shí)別申請(qǐng),導(dǎo)致"意外"發(fā)生院喜。
3.3.3亡蓉、安全性問題
上文介紹的指紋驗(yàn)證Api:public void authenticate (BiometricPrompt.CryptoObject crypto, CancellationSignal cancel, Executor executor, BiometricPrompt.AuthenticationCallback callback)
,若對(duì)第一個(gè)crypto參數(shù)使用方式不正確喷舀,則存在指紋驗(yàn)證被繞過的風(fēng)險(xiǎn)
流程
第一步:調(diào)用authenticate方法砍濒,彈出UI提示用戶輸入指紋-->第二步:用戶驗(yàn)證指紋,用戶驗(yàn)證指紋成功-->第三步:調(diào)用AuthenticationCallback.onAuthenticationSucceeded方法硫麻,執(zhí)行解鎖后邏輯
漏洞
- root手機(jī)
- 通過hook重寫authenticate方法爸邢,在authenticate方法中直接調(diào)用AuthenticationCallback.onAuthenticationSucceeded方法。若應(yīng)用未正確使用crypto參數(shù)庶香,則此方案繞過第二步驗(yàn)證指紋甲棍。
3.4 解決方案
3.4.1简识、UI兼容性問題
若使用BiometricPrompt則具體UI無法由第三方開發(fā)者指定赶掖,若要統(tǒng)一UI,建議使用FingerprintManager
3.4.2七扰、功能性問題
若使用BiometricPrompt奢赂,則彈窗為系統(tǒng)級(jí)彈窗,其展示與消失邏輯無法由
第三方開發(fā)者指定颈走,第三方開發(fā)者唯一可以控制的就是保證調(diào)起指紋識(shí)別流程(即調(diào)用authenticate方法)的時(shí)機(jī)正確膳灶。
3.4.3、安全性問題
方案一
流程:
- 在調(diào)用authicate方法前立由,通過AndroidKeyStore生成一把對(duì)稱秘鑰轧钓,加密串A得到串B,并用這把秘鑰生成crypto對(duì)象傳入authicate方法锐膜。
- 在AuthenticationCallback.onAuthenticationSucceeded方法中取出crypto對(duì)象毕箍,并解密串B得到C,比較A與C道盏,若相等則通過而柑。
- 若跳過驗(yàn)證流程直接調(diào)用AuthenticationCallback.onAuthenticationSucceeded文捶,則比較A與C會(huì)失敗。
問題與總結(jié):
- 攻擊者若在流程中劫持到秘鑰媒咳,并生成crypto對(duì)象傳入粹排,則仍可以繞過
- 兼容性問題小,對(duì)安全級(jí)別要求低的場(chǎng)景推薦使用
方案二
流程:
- 在調(diào)用authicate方法前涩澡,通過AndroidKeyStore生成一對(duì)非對(duì)稱秘鑰顽耳,設(shè)置要訪問這把秘鑰對(duì)必須在生物識(shí)別成功之后,利用公鑰加密串A得到串B筏养,生成crypto對(duì)象傳入authicate方法斧抱。
- 在AuthenticationCallback.onAuthenticationSucceeded方法中取出crypto對(duì)象,利用私鑰解密串B得到C渐溶,比較A與C辉浦,若相等則通過。
- 若跳過驗(yàn)證流程直接調(diào)用AuthenticationCallback.onAuthenticationSucceeded茎辐,則在訪問私鑰解密數(shù)據(jù)時(shí)宪郊,系統(tǒng)會(huì)拋出
android.security.keystore.KeyPermanentlyInvalidatedException: Key permanently invalidated
,無法繼續(xù)執(zhí)行拖陆。
問題與總結(jié):
- 該方案相對(duì)方案一更加安全弛槐,通過AndroidKeystore保證指紋驗(yàn)證流程的不被繞過
- 由于Android碎片化問題,該方案在使用那把非對(duì)稱秘鑰時(shí)依啰,有非常多的兼容性問題
四乎串、總結(jié)
上文詳細(xì)介紹了Android系統(tǒng)提供的指紋接口的使用方式以及使用過程中存在的問題,對(duì)比FIDO及TENCENT SOTER方案速警,我們可以得出以下圖表
比較項(xiàng) | TENCENT SOTER | Android Framework | FIDO |
---|---|---|---|
接入成本 | 較低 | 低 | 高 |
是否需要聯(lián)網(wǎng) | 是 | 依賴方案 | 是 |
兼容性問題 | 少 | 多 | 少 |
用戶隱私保護(hù) | 好(不會(huì)獲取指紋圖案) | 好(不會(huì)獲取指紋圖案) | 好(不會(huì)獲取指紋圖案) |
安全性 | 高 | 依賴方案 | 高 |
綜合以上叹誉,云閃付在對(duì)安全性要求相對(duì)較低的場(chǎng)景(如解鎖),使用Android原生指紋接口配合AndroidKeystore實(shí)現(xiàn)闷旧,無需聯(lián)網(wǎng)长豁,速度快忙灼,兼容性問題少匠襟;在對(duì)安全性要求較高的場(chǎng)景(如支付),選擇采用第三方FIDO解決方案该园,兼容性問題少,安全性高璧亮。