指紋登陸
隨著智能時代的來臨匆帚,人們越來越習(xí)慣于將重要信息和個人隱私存放于智能手機中。這時手機數(shù)據(jù)的安全性就變得尤其重要。通常我們使用口令或密碼來保護設(shè)備去团,但是隨著iPhone和Android手機硬件的逐步升級與支持文搂,使用指紋驗證成為了代替密碼的一種常規(guī)方法适刀。
指紋驗證是指通過手機中的觸摸傳感器來識別用戶。通過這種技術(shù)我們可以使用指紋解鎖設(shè)備或在應(yīng)用中通過指紋授權(quán)使用例如指紋登錄或指紋支付等功能煤蹭。
為什么使用指紋驗證
對于應(yīng)用而言笔喉,使用指紋驗證可以從多方面提升用戶體驗:
指紋驗證是一種更加快捷方便的方法來驗證用戶身份。傳統(tǒng)校驗用戶身份的方法硝皂,通常是使用密碼或口令然遏,要想越安全就需要使用越復(fù)雜的密碼。相較于輸入冗長且復(fù)雜的密碼吧彪,指紋識別僅僅需要的是使用指尖觸碰傳感器完成驗證待侵。這無疑能給用戶帶來更加順暢的使用體驗。
指紋不會被遺忘姨裸。如上一條所說秧倾,通常密碼都是冗長且復(fù)雜的,尤其是不常使用的密碼傀缩,很容易在一段時間后被用戶忘記那先。而使用指紋識別則完全沒有這種煩惱,你可以隨時使用指紋驗證赡艰。
指紋驗證無需找回功能售淡。由于指紋永遠(yuǎn)不會被遺忘,也不會改變慷垮。通常密碼找回的功能對于指紋驗證來說就毫無意義揖闸。
指紋驗證更加安全。通常為了方便記憶密碼料身,用戶傾向于使用方便記憶的信息(比如生日)來生成密碼汤纸,這讓密碼變得很容易被破解。而即便使用了較為復(fù)雜的密碼芹血,也無法保證其擁有和指紋一樣的獨特性和安全性贮泞。一旦密碼被泄露或盜取,其他人能輕易獲取到用戶信息幔烛。
iOS技術(shù)背景
Touch ID
iOS設(shè)備下的指紋識別是通過iOS設(shè)備提供的Touch ID實現(xiàn)啃擦。
Touch ID技術(shù)包括在iOS設(shè)備上的一套先進(jìn)的硬件與軟件系統(tǒng):
在iOS硬件設(shè)備上的HOME按鍵由藍(lán)寶石水晶制成,能作為透鏡獲取到你手指皮膚下紋理的高清圖片
Touch ID會通過你傳入的一系列指紋圖片饿悬,通過算法生成出屬于指紋的數(shù)字標(biāo)識令蛉,存儲于特殊的芯片上
Touch ID只會存儲通過指紋圖片生成的數(shù)字標(biāo)識,所以不用擔(dān)心你真實的指紋泄露乡恕。由于指紋的獨特性言询,Touch ID算出的數(shù)字標(biāo)識能相同的概率是50000之1俯萎,就是50000個不同指紋才可能會有一對可以通過Touch ID相互匹配。所以Touch ID是一項足夠安全的技術(shù)运杭。
Touch ID已經(jīng)備蘋果普遍使用于iTunes Store, App Store和Apple Pay夫啊。微信和支付寶的支付也已經(jīng)使用了Touch ID。所以Touch ID也是一項被廣泛信賴并使用的技術(shù)辆憔。
Secure Enclave
如在介紹Touch ID時介紹的一樣撇眯,Touch ID不會存儲任何關(guān)于指紋的圖片,而是存儲的指紋標(biāo)識虱咧。不過即使是這些數(shù)字標(biāo)識也被iOS存儲于一塊叫做Secure Enclave(安全領(lǐng)域)的芯片上熊榛。你的指紋信息只會被用于比對是否與設(shè)備中存儲的指紋信息進(jìn)行比對,不能被操作系統(tǒng)腕巡,更不會被其他應(yīng)用訪問玄坦。這些信息也不會上傳到蘋果的服務(wù)或者被iCloud等云服務(wù)備份,不可能被用于與其他的指紋庫進(jìn)行比對绘沉。
LocalAuthentication
LocalAuthentication framework是我們的app來使用iOS設(shè)備上生物信息驗證(Touch ID或者Touch ID)的機制煎楣。上文已經(jīng)介紹過,為了最大限度的保護用戶信息的私密性和安全性车伞,iOS上使用了Secure Enclave的方式來將驗證數(shù)據(jù)與設(shè)備上的其他系統(tǒng)隔離择懂。用戶的認(rèn)證信息甚至無法被操作系統(tǒng)訪問,我們通過認(rèn)證得到的只是一條布爾值的結(jié)果另玖。
Keychain
當(dāng)需要存儲私密信息時困曙,你可以使用Keychain。Keychain是由iOS的Security framework提供的服務(wù)谦去,你可以設(shè)置keychain中元素的訪問權(quán)限為每次去讀取這項數(shù)據(jù)時都需要用戶的認(rèn)證(通過Face ID或者Touch ID)慷丽。當(dāng)每次去請求keychian中數(shù)據(jù)訪問權(quán)限時,LocalAuthentiation Framework會通過系統(tǒng)展示相應(yīng)的界面提示用戶錄入數(shù)據(jù)哪轿,然后將這些數(shù)據(jù)傳入Secure Enclave進(jìn)行比對盈魁。比對結(jié)束后,Secure Enclave會成功或失敗的結(jié)果返回窃诉。其間用戶或者操作系統(tǒng)都不會也不能獲取到用戶的指紋信息。
概述
在iOS和Android技術(shù)背景中我們得知:
我們通過指紋識別能獲取到只是指紋是否匹配赤套,并不能得到其他與指紋信息有關(guān)的結(jié)果
但是我們可以存儲私密信息飘痛,并通過指紋獲取訪問權(quán)限
在此基礎(chǔ)上,初步設(shè)計了指紋識別的流程容握。iOS和安卓在指紋識別上的流程由于API的限制不盡相同宣脉,但是大概的步驟基本一致:
1.打開指紋認(rèn)證界面獲取獲取權(quán)限
2.如果步驟1指紋認(rèn)證成功,獲取到權(quán)限后嘗試從設(shè)備中獲取用戶登錄所需密鑰
3.如果步驟2成功獲取到用戶密鑰剔氏,即用戶已經(jīng)綁定了指紋登陸塑猖,那么獲取用戶密鑰登陸
4.如果步驟2未能獲取到用戶密鑰竹祷,即用戶還未綁定指紋登陸,那么開始綁定指紋的流程
5.綁定指紋的流程可以分為前端和后端的工作羊苟,先由后端生成用戶登陸所需的獨特密鑰傳回給前端
6.前端收到密鑰后將密鑰存儲于本地設(shè)備中
7.使用獲取到的密鑰就能成功登陸
簡化流程如圖:
iOS實現(xiàn)方案
iOS上的指紋登陸方案的主題內(nèi)容為:
使用Security framework將用戶密鑰信息存儲于keychain中
使用LocalAuthentication framework來驗證用戶指紋信息塑陵,并且獲取到keychain中的密鑰訪問權(quán)限
配置工程
要使用Touch ID和Keychain的功能,首先需要將需要的framework添加到工程中蜡励。打開工程后選擇對應(yīng)的Target后點擊Build Phases > Link Binary With Libraries令花,點擊+號添加LocalAuthentication和Security兩個framework。
TouchID API使用
1.添加頭文件
#import <LocalAuthentication/LocalAuthentication.h>
2.判斷系統(tǒng)版本
//首先判斷版本
if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) {
NSLog(@"系統(tǒng)版本不支持TouchID");
return;
}
3.LAPolicy
在這里簡單介紹一下LAPolicy
,它是一個枚舉.我們根據(jù)自己的需要選擇LAPolicy凉倚,它提供兩個值:
LAPolicyDeviceOwnerAuthenticationWithBiometrics
和LAPolicyDeviceOwnerAuthentication
.
<1>. LAPolicyDeviceOwnerAuthenticationWithBiometrics
是支持iOS8以上系統(tǒng),使用該設(shè)備的TouchID進(jìn)行驗證,當(dāng)輸入TouchID驗證5次失敗后,TouchID被鎖定,只能通過鎖屏后解鎖設(shè)備時輸入正確的解鎖密碼來解鎖TouchID兼都。
<2>.LAPolicyDeviceOwnerAuthentication
是支持iOS9以上系統(tǒng),使用該設(shè)備的TouchID或設(shè)備密碼進(jìn)行驗證,當(dāng)輸入TouchID驗證5次失敗后稽寒,TouchID被鎖定扮碧,會觸發(fā)設(shè)備密碼頁面進(jìn)行驗證。
4. canEvaluatePolicy
使用canEvaluatePolicy
方法判斷設(shè)備是否支持TouchID杏糙,返回BOOL
為YES
芬萍,該設(shè)備支持TouchID。
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
error為返回驗證錯誤碼.具體不解釋了.
4. evaluatedPolicyDomainState
context.evaluatedPolicyDomainState用于判斷設(shè)備上的指紋是否被更改搔啊,在LAContext被創(chuàng)建的時候柬祠,evaluatedPolicyDomainState才生效,可在TouchID驗證成功時负芋,將它記錄下來漫蛔,用于下次使用TouchID時校驗,提高安全性旧蛾。
5. evaluatePolicy
evaluatePolicy方法是對TouchID進(jìn)行驗證,Block回調(diào)中如果success為YES則驗證成功,為NO驗證失敗,并對error進(jìn)行解析.
- (IBAction)loginButtonClick:(UIButton *)sender {
//首先判斷版本
if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) {
NSLog(@"系統(tǒng)版本不支持TouchID");
return;
}
LAContext *context = [[LAContext alloc] init];
context.localizedFallbackTitle = @"輸入密碼";
if (@available(iOS 10.0, *)) {
// context.localizedCancelTitle = @"22222";
} else {
// Fallback on earlier versions
}
NSError *error = nil;
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"通過Home鍵驗證已有手機指紋" reply:^(BOOL success, NSError * _Nullable error) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 驗證成功");
});
}else if(error){
switch (error.code) {
case LAErrorAuthenticationFailed:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 驗證失敗");
});
break;
}
case LAErrorUserCancel:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 被用戶手動取消");
});
}
break;
case LAErrorUserFallback:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"用戶不使用TouchID,選擇手動輸入密碼");
});
}
break;
case LAErrorSystemCancel:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 被系統(tǒng)取消 (如遇到來電,鎖屏,按了Home鍵等)");
});
}
break;
case LAErrorPasscodeNotSet:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 無法啟動,因為用戶沒有設(shè)置密碼");
});
}
break;
case LAErrorTouchIDNotEnrolled:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 無法啟動,因為用戶沒有設(shè)置TouchID");
});
}
break;
case LAErrorTouchIDNotAvailable:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 無效");
});
}
break;
case LAErrorTouchIDLockout:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 被鎖定(連續(xù)多次驗證TouchID失敗,系統(tǒng)需要用戶手動輸入密碼)");
});
}
break;
case LAErrorAppCancel:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"當(dāng)前軟件被掛起并取消了授權(quán) (如App進(jìn)入了后臺等)");
});
}
break;
case LAErrorInvalidContext:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"當(dāng)前軟件被掛起并取消了授權(quán) (LAContext對象無效)");
});
}
break;
default:
break;
}
}
}];
}else{
NSLog(@"當(dāng)前設(shè)備不支持TouchID");
}
}
上面這個代碼, 是整個TouchID的核心,也幾乎是所有代碼了.
驗證
驗證必須使用真機
總結(jié):TouchID使用起來不難,重要的是使用流程邏輯.
以登錄為例,一般來說流程是這樣的:
1.開啟指紋登錄:首次登陸使用密碼登錄,登錄后,可以設(shè)置一個開啟指紋ID登錄的按鈕,來進(jìn)行指紋認(rèn)證.
2.驗證:檢測是否支持TouchID.
3.生成設(shè)備賬號/密碼:TouchID驗證通過后莽龟,根據(jù)當(dāng)前已登錄的賬號和硬件設(shè)備Token,生成設(shè)備賬號/密碼(規(guī)則可自定锨天,密碼要長要復(fù)雜)毯盈,并保存在keychain;
4.綁定:生成設(shè)備賬號/密碼后病袄,將原賬號及設(shè)備賬號/密碼搂赋,加密后(題主使用的是RSA加密)發(fā)送到服務(wù)端進(jìn)行綁定;
5.成功:驗證原賬號及設(shè)備賬號有效后益缠,返回相應(yīng)狀態(tài)脑奠,綁定成功則完成整個TouchID(設(shè)備)綁定流程。
注意的坑
在ios10指紋驗證錯誤過多會報錯幅慌,然后不會彈出系統(tǒng)密碼輸入界面:
打印error.code宋欺,是:-8
打印error.localizedDescription,是:Biometry is locked out
上網(wǎng)查到ios9以前會彈出系統(tǒng)密碼輸入界面。
ios10及以后呢齿诞?
ios9以前這樣寫:
//是否支持touchid
[_context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]
//驗證指紋是否匹配
[_context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"通過home鍵驗證已有指紋" reply:^(BOOL success, NSError * _Nullable error) {}
IOS10上只需把上面兩個地方的 LAPolicyDeviceOwnerAuthenticationWithBiometrics
換成
LAPolicyDeviceOwnerAuthentication
即可酸休。
ios10這樣寫
//是否支持touchid
[_context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]
//報錯碼為-8時,調(diào)用此方法會彈出系統(tǒng)密碼輸入界面
[_context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:@"指紋驗證錯誤次數(shù)過多祷杈,請輸入密碼" reply:^(BOOL success, NSError * _Nullable error){
當(dāng)然為了適配ios8,9,10可以在適當(dāng)?shù)臅r候斑司,做適當(dāng)?shù)牟僮鳌?/p>
參考鏈接:
iOS指紋登陸
iOS 指紋登錄(TouchID)集成方案
IOS TouchId開發(fā) Biometry is locked out
iOS指紋識別登錄流程及實現(xiàn)