簡述: 在類似支付寶為首的應(yīng)用以及各種理財?shù)壬婕板X財對安全性要求較高的應(yīng)用中,目前普遍對關(guān)鍵數(shù)據(jù)都做了安全訪問限制,比如通過手勢密碼、指紋密碼等手段,本章主要分析一下iOS開發(fā)中指紋識別的一些坑和技術(shù)要點。
指紋識別
指紋識別是iPhone5s iOS8.0之后推出的功能,需要硬件以及軟件的支持。指紋識別的功能定義在系統(tǒng)框架<LocalAuthentication/LocalAuthentication.h>
中,并且在app中集成指紋識別是跟系統(tǒng)解鎖iPhone用的一套指紋識別,就是說假如在app中指紋識別錯誤了5次(iOS 系統(tǒng)默認(rèn)指紋識別錯誤5次后,指紋識別會被判定為無效狀態(tài)),那么不僅app中的指紋識別系統(tǒng)是無效的,系統(tǒng)的iPhone指紋識別解鎖系統(tǒng)也是無效的,必須輸入iPhone解鎖口令碼驗證之后,指紋識別才會被系統(tǒng)重新判別為有效!指紋識別有兩個模式:
typedef NS_ENUM(NSInteger, LAPolicy)
{
//8.0支持的API
LAPolicyDeviceOwnerAuthenticationWithBiometrics NS_ENUM_AVAILABLE(NA, 8_0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0) = kLAPolicyDeviceOwnerAuthenticationWithBiometrics,
//9.0支持的API
LAPolicyDeviceOwnerAuthentication NS_ENUM_AVAILABLE(10_11, 9_0) = kLAPolicyDeviceOwnerAuthentication
} NS_ENUM_AVAILABLE(10_10, 8_0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0);
需要注意的是開發(fā)的時候一定要注意區(qū)分iOS系統(tǒng)的版本選用不同的API,避免出現(xiàn)重大問題。同時這兩個不同的模式的響應(yīng)方式也是不同的:
LAPolicyDeviceOwnerAuthenticationWithBiometrics
生物指紋識別。驗證彈框有兩個按鈕,第一個是取消按鈕,第二個按鈕可以自定義標(biāo)題名稱(默認(rèn)是"輸入密碼")。只有在第一次指紋驗證失敗后才會出現(xiàn)第二個按鈕,這種鑒定方式的第二個按鈕的功能自定義,第二個按鈕的功能不做處理的話不會有任何響應(yīng)。
前三次指紋驗證失敗,指紋驗證框不再彈出。再次重新進(jìn)入驗證,還有兩次驗證機(jī)會,如果還是驗證失敗,TOUCH ID 被鎖住不再繼續(xù)彈出指紋驗證框。(在iOS10.0以下系統(tǒng)中,不包括iOS 10.0,以后每次進(jìn)來驗證都是調(diào)用系統(tǒng)的設(shè)備密碼直至輸入正確的設(shè)備密碼方可解除TOUCH ID鎖,但是在iOS 10.0系統(tǒng)中,指紋識別累計錯誤5次系統(tǒng)判定指紋無效后不會彈出系統(tǒng)的設(shè)備密碼輸入頁面,尷尬......開發(fā)的時候誰曉得iOS 10有這個大坑,被坑慘了。
Talk is cheap,show me the code.
- (void)checkTouchID{
LAContext *laContext = [[LAContext alloc] init];
//去掉 “輸入密碼”,這行代碼可以去掉“輸入密碼”的按鈕
laContext.localizedFallbackTitle = @"";
NSError *error;
if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
NSLog(@"指紋識別有效");
[laContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:@"通過Home鍵驗證已有手機(jī)指紋"
reply:^(BOOL success, NSError *error) {
if (success) {
//指紋驗證通過
}else if (error.code == kLAErrorUserCancel){
//用戶點擊取消
}else if (error.code == kLAErrorAuthenticationFailed){
//用戶驗證沒有通過,指紋錯誤
}
}];
}else {
NSLog(@"指紋識別無效%@",error.localizedDescription);
//不支持指紋識別,LOG出錯誤詳情
switch (error.code) {
case LAErrorTouchIDNotEnrolled:
{
NSLog(@"TouchID is not enrolled");
break;
}
case LAErrorPasscodeNotSet:
{
NSLog(@"A passcode has not been set");
break;
}
default:
{
NSLog(@"TouchID not available");
break;
}
}
}
}
在iOS10系統(tǒng)中,指紋識別錯誤5次后,調(diào)用[laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]
就會返回NO,在- (void)checkTouchID
方法中,就會打印信息:NSLog(@"指紋識別無效%@",error.localizedDescription);
代碼會跳到這個位置。
在iOS9、iOS8 系統(tǒng)中,指紋識別錯誤5次后,調(diào)用[laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]
就會返回YES,在- (void)checkTouchID
方法中,就會打印信息:指紋識別有效。 代碼會跳到這個位置。NSLog(@"指紋識別有效");
LAPolicyDeviceOwnerAuthentication
生物指紋識別或系統(tǒng)密碼驗證。注意這個policy是9.0的API,對于8.0系統(tǒng)的手機(jī)不能使用。如果TOUCH ID 可用,且已經(jīng)錄入指紋,則優(yōu)先調(diào)用指紋驗證。其次是調(diào)用系統(tǒng)密碼驗證,如果沒有開啟設(shè)備密碼,則不可以使用這種驗證方式。指紋識別驗證失敗三次將自動彈出設(shè)備密碼輸入框,如果不進(jìn)行密碼輸入。再次進(jìn)來還可以有兩次機(jī)會驗證指紋,如果都失敗則TOUCH ID被鎖住。以后也只能彈出設(shè)備密碼輸入框。補(bǔ)充:值得注意的是在iOS9系統(tǒng)中,前三次驗證失敗會自動彈出密碼驗證框,后兩次驗證失敗后不會自動彈出密碼驗證框。而在iOS 10系統(tǒng)中,前三次驗證失敗或者后兩次驗證失敗,都會自動彈出密碼驗證框。
- (void)checkTouchID{
LAContext *laContext = [[LAContext alloc] init];
//去掉 “輸入密碼”
laContext.localizedFallbackTitle = @"";
NSError *error;
if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error]) {
NSLog(@"指紋識別有效");
[laContext evaluatePolicy:LAPolicyDeviceOwnerAuthentication
localizedReason:@"通過Home鍵驗證已有手機(jī)指紋"
reply:^(BOOL success, NSError *error) {
if (success) {
//指紋驗證通過
}else if (error.code == kLAErrorUserCancel){
//用戶點擊取消
}else if (error.code == kLAErrorAuthenticationFailed){
//用戶驗證沒有通過,指紋錯誤
}
}];
}else {
NSLog(@"指紋識別無效%@",error.localizedDescription);
//不支持指紋識別,LOG出錯誤詳情
switch (error.code) {
case LAErrorTouchIDNotEnrolled:
{
NSLog(@"TouchID is not enrolled");
break;
}
case LAErrorPasscodeNotSet:
{
NSLog(@"A passcode has not been set");
break;
}
default:
{
NSLog(@"TouchID not available");
break;
}
}
}
}
在iOS9、iOS 10系統(tǒng)中,這個policy默認(rèn)也有兩個按鈕,第一次驗證指紋識別后會顯示兩個按鈕,第二個按鈕是"輸入密碼",默認(rèn)點擊第二個按鈕會彈出設(shè)備密碼輸入框。
異常情況
上面所描述的是iOS系統(tǒng)設(shè)置了口令密碼,同時也添加了指紋的情況。但是用戶在使用過程中可能會出現(xiàn)各種情況,下面分析一下兩種policy在不同系統(tǒng)上,只有口令密碼、只有指紋、沒有口令也沒有指紋的情況下所作出的響應(yīng),通過打印輸出結(jié)果確定代碼的跳轉(zhuǎn)位置。
LAPolicyDeviceOwnerAuthenticationWithBiometrics
- (void)checkTouchID{
LAContext *laContext = [[LAContext alloc] init];
//去掉 “輸入密碼”
laContext.localizedFallbackTitle = @"";
NSError *error;
if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
NSLog(@"指紋識別有效");
}else {
NSLog(@"指紋識別無效%@",error.localizedDescription);
}
}
iOS8系統(tǒng):
在只有口令密碼的情況下打印結(jié)果:NSLog(@"指紋識別無效%@",error.localizedDescription);
在只有指紋的情況下打印結(jié)果: NSLog(@"指紋識別無效%@",error.localizedDescription);
在沒有口令也沒有指紋的情況下打印結(jié)果:NSLog(@"指紋識別無效%@",error.localizedDescription);
iOS9系統(tǒng):
在只有口令密碼的情況下打印結(jié)果:NSLog(@"指紋識別無效%@",error.localizedDescription);
在只有指紋的情況下打印結(jié)果: NSLog(@"指紋識別無效%@",error.localizedDescription);
在沒有口令也沒有指紋的情況下打印結(jié)果:NSLog(@"指紋識別無效%@",error.localizedDescription);
iOS10系統(tǒng):
在只有口令密碼的情況下打印結(jié)果:NSLog(@"指紋識別無效%@",error.localizedDescription);
在只有指紋的情況下打印結(jié)果: NSLog(@"指紋識別無效%@",error.localizedDescription);
在沒有口令也沒有指紋的情況下打印結(jié)果:NSLog(@"指紋識別無效%@",error.localizedDescription);
分析可知,在LAPolicyDeviceOwnerAuthenticationWithBiometrics
下必須系統(tǒng)口令碼和指紋同時是存在的,才會判定指紋系統(tǒng)是可用的。
LAPolicyDeviceOwnerAuthentication
- (void)checkTouchID{
LAContext *laContext = [[LAContext alloc] init];
//去掉 “輸入密碼”
laContext.localizedFallbackTitle = @"";
NSError *error;
if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error]) {
NSLog(@"指紋識別有效");
}else {
NSLog(@"指紋識別無效%@",error.localizedDescription);
}
}
iOS9系統(tǒng):
在只有口令密碼的情況下打印結(jié)果:NSLog(@"指紋識別有效");
在只有指紋的情況下打印結(jié)果: NSLog(@"指紋識別無效%@",error.localizedDescription);
在沒有口令也沒有指紋的情況下打印結(jié)果:NSLog(@"指紋識別無效%@",error.localizedDescription);
iOS10系統(tǒng):
在只有口令密碼的情況下打印結(jié)果:NSLog(@"指紋識別有效");
在只有指紋的情況下打印結(jié)果: NSLog(@"指紋識別無效%@",error.localizedDescription);
在沒有口令也沒有指紋的情況下打印結(jié)果:NSLog(@"指紋識別無效%@",error.localizedDescription);
綜合iOS9、iOS10在policy:LAPolicyDeviceOwnerAuthentication
下的表現(xiàn),只要開啟了系統(tǒng)口令碼,就判定指紋系統(tǒng)可用,更加印證了 如果沒有開啟設(shè)備密碼,則不可以使用這種驗證方式。
指紋鑒定錯誤碼
1、 驗證(指紋/密碼)不能開啟的錯誤信息(指紋系統(tǒng)被判定為無效):
LAErrorPasscodeNotSet : 設(shè)備密碼未設(shè)置
LAErrorTouchIDNotAvailable : TOUCH ID不可用
LAErrorTouchIDNotEnrolled : 指紋未錄入
LAErrorTouchIDLockout : TOUCH ID被鎖定
LAErrorAppCancel : APP調(diào)用了- (void)invalidate
方法使LAContext
失效
LAErrorInvalidContext : 實例化的LAContext
對象失效,再次調(diào)用evaluation...
方法則會彈出此錯誤信息
2、 其他錯誤信息(指紋系統(tǒng)判定有效,但是驗證指紋錯誤):
LAErrorAuthenticationFailed : 鑒定失敗
LAErrorUserCancel : 用戶取消
LAErrorUserFallback : 用戶選擇輸入密碼
LAErrorSystemCancel : 系統(tǒng)取消(如:另外一個應(yīng)用進(jìn)入前臺)
總結(jié)
上面分析了指紋識別的兩種policy在不同系統(tǒng)上、不同狀態(tài)下的各種響應(yīng)狀態(tài),并且列出了一些指紋鑒定錯誤碼,相信對整個API的作用有詳盡的認(rèn)識,開發(fā)出類似支付寶指紋識別的流程也不是難事,希望可以幫助更多人。