iOS指紋識別

指紋登陸

隨著智能時代的來臨,人們越來越習慣于將重要信息和個人隱私存放于智能手機中。這時手機數據的安全性就變得尤其重要。通常我們使用口令或密碼來保護設備,但是隨著iPhone和Android手機硬件的逐步升級與支持,使用指紋驗證成為了代替密碼的一種常規方法。

指紋驗證是指通過手機中的觸摸傳感器來識別用戶。通過這種技術我們可以使用指紋解鎖設備或在應用中通過指紋授權使用例如指紋登錄或指紋支付等功能。

為什么使用指紋驗證

對于應用而言,使用指紋驗證可以從多方面提升用戶體驗:

指紋驗證是一種更加快捷方便的方法來驗證用戶身份。傳統校驗用戶身份的方法,通常是使用密碼或口令,要想越安全就需要使用越復雜的密碼。相較于輸入冗長且復雜的密碼,指紋識別僅僅需要的是使用指尖觸碰傳感器完成驗證。這無疑能給用戶帶來更加順暢的使用體驗。

指紋不會被遺忘。如上一條所說,通常密碼都是冗長且復雜的,尤其是不常使用的密碼,很容易在一段時間后被用戶忘記。而使用指紋識別則完全沒有這種煩惱,你可以隨時使用指紋驗證。

指紋驗證無需找回功能。由于指紋永遠不會被遺忘,也不會改變。通常密碼找回的功能對于指紋驗證來說就毫無意義。

指紋驗證更加安全。通常為了方便記憶密碼,用戶傾向于使用方便記憶的信息(比如生日)來生成密碼,這讓密碼變得很容易被破解。而即便使用了較為復雜的密碼,也無法保證其擁有和指紋一樣的獨特性和安全性。一旦密碼被泄露或盜取,其他人能輕易獲取到用戶信息。

iOS技術背景

Touch ID

iOS設備下的指紋識別是通過iOS設備提供的Touch ID實現。

Touch ID技術包括在iOS設備上的一套先進的硬件與軟件系統:

  • 在iOS硬件設備上的HOME按鍵由藍寶石水晶制成,能作為透鏡獲取到你手指皮膚下紋理的高清圖片

  • Touch ID會通過你傳入的一系列指紋圖片,通過算法生成出屬于指紋的數字標識,存儲于特殊的芯片上

Touch ID只會存儲通過指紋圖片生成的數字標識,所以不用擔心你真實的指紋泄露。由于指紋的獨特性,Touch ID算出的數字標識能相同的概率是50000之1,就是50000個不同指紋才可能會有一對可以通過Touch ID相互匹配。所以Touch ID是一項足夠安全的技術。

Touch ID已經備蘋果普遍使用于iTunes Store, App Store和Apple Pay。微信和支付寶的支付也已經使用了Touch ID。所以Touch ID也是一項被廣泛信賴并使用的技術。

Secure Enclave

如在介紹Touch ID時介紹的一樣,Touch ID不會存儲任何關于指紋的圖片,而是存儲的指紋標識。不過即使是這些數字標識也被iOS存儲于一塊叫做Secure Enclave(安全領域)的芯片上。你的指紋信息只會被用于比對是否與設備中存儲的指紋信息進行比對,不能被操作系統,更不會被其他應用訪問。這些信息也不會上傳到蘋果的服務或者被iCloud等云服務備份,不可能被用于與其他的指紋庫進行比對。

LocalAuthentication

LocalAuthentication framework是我們的app來使用iOS設備上生物信息驗證(Touch ID或者Touch ID)的機制。上文已經介紹過,為了最大限度的保護用戶信息的私密性和安全性,iOS上使用了Secure Enclave的方式來將驗證數據與設備上的其他系統隔離。用戶的認證信息甚至無法被操作系統訪問,我們通過認證得到的只是一條布爾值的結果。

Keychain

當需要存儲私密信息時,你可以使用Keychain。Keychain是由iOS的Security framework提供的服務,你可以設置keychain中元素的訪問權限為每次去讀取這項數據時都需要用戶的認證(通過Face ID或者Touch ID)。當每次去請求keychian中數據訪問權限時,LocalAuthentiation Framework會通過系統展示相應的界面提示用戶錄入數據,然后將這些數據傳入Secure Enclave進行比對。比對結束后,Secure Enclave會成功或失敗的結果返回。其間用戶或者操作系統都不會也不能獲取到用戶的指紋信息。

image.png

概述

在iOS和Android技術背景中我們得知:

我們通過指紋識別能獲取到只是指紋是否匹配,并不能得到其他與指紋信息有關的結果

但是我們可以存儲私密信息,并通過指紋獲取訪問權限

在此基礎上,初步設計了指紋識別的流程。iOS和安卓在指紋識別上的流程由于API的限制不盡相同,但是大概的步驟基本一致:

1.打開指紋認證界面獲取獲取權限

2.如果步驟1指紋認證成功,獲取到權限后嘗試從設備中獲取用戶登錄所需密鑰

3.如果步驟2成功獲取到用戶密鑰,即用戶已經綁定了指紋登陸,那么獲取用戶密鑰登陸

4.如果步驟2未能獲取到用戶密鑰,即用戶還未綁定指紋登陸,那么開始綁定指紋的流程

5.綁定指紋的流程可以分為前端和后端的工作,先由后端生成用戶登陸所需的獨特密鑰傳回給前端

6.前端收到密鑰后將密鑰存儲于本地設備中

7.使用獲取到的密鑰就能成功登陸

簡化流程如圖:

image.png

iOS實現方案

iOS上的指紋登陸方案的主題內容為:

  • 使用Security framework將用戶密鑰信息存儲于keychain中

  • 使用LocalAuthentication framework來驗證用戶指紋信息,并且獲取到keychain中的密鑰訪問權限

配置工程

要使用Touch ID和Keychain的功能,首先需要將需要的framework添加到工程中。打開工程后選擇對應的Target后點擊Build Phases > Link Binary With Libraries,點擊+號添加LocalAuthentication和Security兩個framework。

image.png

TouchID API使用

1.添加頭文件

#import <LocalAuthentication/LocalAuthentication.h>

2.判斷系統版本

 //首先判斷版本
if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) {
      NSLog(@"系統版本不支持TouchID");
      return;
}

3.LAPolicy

在這里簡單介紹一下LAPolicy,它是一個枚舉.我們根據自己的需要選擇LAPolicy,它提供兩個值:
LAPolicyDeviceOwnerAuthenticationWithBiometricsLAPolicyDeviceOwnerAuthentication.
<1>. LAPolicyDeviceOwnerAuthenticationWithBiometrics是支持iOS8以上系統,使用該設備的TouchID進行驗證,當輸入TouchID驗證5次失敗后,TouchID被鎖定,只能通過鎖屏后解鎖設備時輸入正確的解鎖密碼來解鎖TouchID。
<2>.LAPolicyDeviceOwnerAuthentication是支持iOS9以上系統,使用該設備的TouchID或設備密碼進行驗證,當輸入TouchID驗證5次失敗后,TouchID被鎖定,會觸發設備密碼頁面進行驗證。

4. canEvaluatePolicy

使用canEvaluatePolicy方法判斷設備是否支持TouchID,返回BOOLYES,該設備支持TouchID。

 if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {

error為返回驗證錯誤碼.具體不解釋了.

4. evaluatedPolicyDomainState

context.evaluatedPolicyDomainState用于判斷設備上的指紋是否被更改,在LAContext被創建的時候,evaluatedPolicyDomainState才生效,可在TouchID驗證成功時,將它記錄下來,用于下次使用TouchID時校驗,提高安全性。

5. evaluatePolicy

evaluatePolicy方法是對TouchID進行驗證,Block回調中如果success為YES則驗證成功,為NO驗證失敗,并對error進行解析.

- (IBAction)loginButtonClick:(UIButton *)sender {

    //首先判斷版本
    if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) {
        NSLog(@"系統版本不支持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 被系統取消 (如遇到來電,鎖屏,按了Home鍵等)");
                        });
                    }
                        break;
                    case LAErrorPasscodeNotSet:{
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"TouchID 無法啟動,因為用戶沒有設置密碼");
                        });
                    }
                        break;
                    case LAErrorTouchIDNotEnrolled:{
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"TouchID 無法啟動,因為用戶沒有設置TouchID");
                        });
                    }
                        break;
                    case LAErrorTouchIDNotAvailable:{
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"TouchID 無效");
                        });
                    }
                        break;
                    case LAErrorTouchIDLockout:{
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"TouchID 被鎖定(連續多次驗證TouchID失敗,系統需要用戶手動輸入密碼)");
                        });
                    }
                        break;
                    case LAErrorAppCancel:{
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"當前軟件被掛起并取消了授權 (如App進入了后臺等)");
                        });
                    }
                        break;
                    case LAErrorInvalidContext:{
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"當前軟件被掛起并取消了授權 (LAContext對象無效)");
                        });
                    }
                        break;
                    default:
                        break;
                }
            }
        }];

    }else{
        NSLog(@"當前設備不支持TouchID");
    }
}

上面這個代碼, 是整個TouchID的核心,也幾乎是所有代碼了.

驗證

驗證必須使用真機

image
image

總結:TouchID使用起來不難,重要的是使用流程邏輯.

以登錄為例,一般來說流程是這樣的:
1.開啟指紋登錄:首次登陸使用密碼登錄,登錄后,可以設置一個開啟指紋ID登錄的按鈕,來進行指紋認證.
2.驗證:檢測是否支持TouchID.
3.生成設備賬號/密碼:TouchID驗證通過后,根據當前已登錄的賬號和硬件設備Token,生成設備賬號/密碼(規則可自定,密碼要長要復雜),并保存在keychain;
4.綁定:生成設備賬號/密碼后,將原賬號及設備賬號/密碼,加密后(題主使用的是RSA加密)發送到服務端進行綁定;
5.成功:驗證原賬號及設備賬號有效后,返回相應狀態,綁定成功則完成整個TouchID(設備)綁定流程。

注意的坑

在ios10指紋驗證錯誤過多會報錯,然后不會彈出系統密碼輸入界面:

打印error.code,是:-8
打印error.localizedDescription,是:Biometry is locked out
上網查到ios9以前會彈出系統密碼輸入界面。

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時,調用此方法會彈出系統密碼輸入界面

[_context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:@"指紋驗證錯誤次數過多,請輸入密碼" reply:^(BOOL success, NSError * _Nullable error){

當然為了適配ios8,9,10可以在適當的時候,做適當的操作。

參考鏈接:
iOS指紋登陸
iOS 指紋登錄(TouchID)集成方案
IOS TouchId開發 Biometry is locked out
iOS指紋識別登錄流程及實現

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374