iOS指纹识别

简述: 在类似支付宝为首的应用以及各种理财等涉及钱财对安全性要求较高的应用中,目前普遍对关键数据都做了安全访问限制,比如通过手势密码、指纹密码等手段,本章主要分析一下iOS开发中指纹识别的一些坑和技术要点。

指纹识别

指纹识别是iPhone5s iOS8.0之后推出的功能,需要硬件以及软件的支持。指纹识别的功能定义在系统框架<LocalAuthentication/LocalAuthentication.h>中,并且在app中集成指纹识别是跟系统解锁iPhone用的一套指纹识别,就是说假如在app中指纹识别错误了5次(iOS 系统默认指纹识别错误5次后,指纹识别会被判定为无效状态),那么不仅app中的指纹识别系统是无效的,系统的iPhone指纹识别解锁系统也是无效的,必须输入iPhone解锁口令码验证之后,指纹识别才会被系统重新判别为有效!指纹识别有两个模式:

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);

需要注意的是开发的时候一定要注意区分iOS系统的版本选用不同的API,避免出现重大问题。同时这两个不同的模式的响应方式也是不同的:

LAPolicyDeviceOwnerAuthenticationWithBiometrics

生物指纹识别。验证弹框有两个按钮,第一个是取消按钮,第二个按钮可以自定义标题名称(默认是"输入密码")。只有在第一次指纹验证失败后才会出现第二个按钮,这种鉴定方式的第二个按钮的功能自定义,第二个按钮的功能不做处理的话不会有任何响应。

图片.png

前三次指纹验证失败,指纹验证框不再弹出。再次重新进入验证,还有两次验证机会,如果还是验证失败,TOUCH ID 被锁住不再继续弹出指纹验证框。(在iOS10.0以下系统中,不包括iOS 10.0,以后每次进来验证都是调用系统的设备密码直至输入正确的设备密码方可解除TOUCH ID锁,但是在iOS 10.0系统中,指纹识别累计错误5次系统判定指纹无效后不会弹出系统的设备密码输入页面,尴尬......开发的时候谁晓得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键验证已有手机指纹"
                            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系统中,指纹识别错误5次后,调用[laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]就会返回NO,在- (void)checkTouchID方法中,就会打印信息:NSLog(@"指纹识别无效%@",error.localizedDescription);代码会跳到这个位置。

在iOS9、iOS8 系统中,指纹识别错误5次后,调用[laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]就会返回YES,在- (void)checkTouchID方法中,就会打印信息:指纹识别有效。 代码会跳到这个位置。NSLog(@"指纹识别有效");

LAPolicyDeviceOwnerAuthentication

生物指纹识别或系统密码验证。注意这个policy是9.0的API,对于8.0系统的手机不能使用。如果TOUCH ID 可用,且已经录入指纹,则优先调用指纹验证。其次是调用系统密码验证,如果没有开启设备密码,则不可以使用这种验证方式。指纹识别验证失败三次将自动弹出设备密码输入框,如果不进行密码输入。再次进来还可以有两次机会验证指纹,如果都失败则TOUCH ID被锁住。以后也只能弹出设备密码输入框。补充:值得注意的是在iOS9系统中,前三次验证失败会自动弹出密码验证框,后两次验证失败后不会自动弹出密码验证框。而在iOS 10系统中,前三次验证失败或者后两次验证失败,都会自动弹出密码验证框。

- (void)checkTouchID{
    
    LAContext *laContext = [[LAContext alloc] init];
    //去掉 “输入密码”
    laContext.localizedFallbackTitle = @"";
    NSError *error;
    if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error]) {
        NSLog(@"指纹识别有效");
        [laContext evaluatePolicy:LAPolicyDeviceOwnerAuthentication
                  localizedReason:@"通过Home键验证已有手机指纹"
                            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系统中,这个policy默认也有两个按钮,第一次验证指纹识别后会显示两个按钮,第二个按钮是"输入密码",默认点击第二个按钮会弹出设备密码输入框。

异常情况

上面所描述的是iOS系统设置了口令密码,同时也添加了指纹的情况。但是用户在使用过程中可能会出现各种情况,下面分析一下两种policy在不同系统上,只有口令密码、只有指纹、没有口令也没有指纹的情况下所作出的响应,通过打印输出结果确定代码的跳转位置。

LAPolicyDeviceOwnerAuthenticationWithBiometrics
- (void)checkTouchID{
    LAContext *laContext = [[LAContext alloc] init];
    //去掉 “输入密码”
    laContext.localizedFallbackTitle = @"";
    NSError *error;
    if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
        NSLog(@"指纹识别有效");
    }else {
        NSLog(@"指纹识别无效%@",error.localizedDescription);
    }
}

iOS8系统:
在只有口令密码的情况下打印结果:NSLog(@"指纹识别无效%@",error.localizedDescription);
在只有指纹的情况下打印结果: NSLog(@"指纹识别无效%@",error.localizedDescription);
在没有口令也没有指纹的情况下打印结果:NSLog(@"指纹识别无效%@",error.localizedDescription);

iOS9系统:
在只有口令密码的情况下打印结果:NSLog(@"指纹识别无效%@",error.localizedDescription);
在只有指纹的情况下打印结果: NSLog(@"指纹识别无效%@",error.localizedDescription);
在没有口令也没有指纹的情况下打印结果:NSLog(@"指纹识别无效%@",error.localizedDescription);

iOS10系统:
在只有口令密码的情况下打印结果:NSLog(@"指纹识别无效%@",error.localizedDescription);
在只有指纹的情况下打印结果: NSLog(@"指纹识别无效%@",error.localizedDescription);
在没有口令也没有指纹的情况下打印结果:NSLog(@"指纹识别无效%@",error.localizedDescription);
分析可知,在LAPolicyDeviceOwnerAuthenticationWithBiometrics下必须系统口令码和指纹同时是存在的,才会判定指纹系统是可用的。

LAPolicyDeviceOwnerAuthentication
- (void)checkTouchID{
    
    LAContext *laContext = [[LAContext alloc] init];
    //去掉 “输入密码”
    laContext.localizedFallbackTitle = @"";
    NSError *error;
    if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error]) {
        NSLog(@"指纹识别有效");
    }else {
        NSLog(@"指纹识别无效%@",error.localizedDescription);
    }
}

iOS9系统:
在只有口令密码的情况下打印结果:NSLog(@"指纹识别有效");
在只有指纹的情况下打印结果: NSLog(@"指纹识别无效%@",error.localizedDescription);
在没有口令也没有指纹的情况下打印结果:NSLog(@"指纹识别无效%@",error.localizedDescription);

iOS10系统:
在只有口令密码的情况下打印结果:NSLog(@"指纹识别有效");
在只有指纹的情况下打印结果: NSLog(@"指纹识别无效%@",error.localizedDescription);
在没有口令也没有指纹的情况下打印结果:NSLog(@"指纹识别无效%@",error.localizedDescription);
综合iOS9、iOS10在policy:LAPolicyDeviceOwnerAuthentication下的表现,只要开启了系统口令码,就判定指纹系统可用,更加印证了 如果没有开启设备密码,则不可以使用这种验证方式。

指纹鉴定错误码

1、 验证(指纹/密码)不能开启的错误信息(指纹系统被判定为无效):
LAErrorPasscodeNotSet : 设备密码未设置
LAErrorTouchIDNotAvailable : TOUCH ID不可用
LAErrorTouchIDNotEnrolled : 指纹未录入
LAErrorTouchIDLockout : TOUCH ID被锁定
LAErrorAppCancel : APP调用了- (void)invalidate
方法使LAContext
失效
LAErrorInvalidContext : 实例化的LAContext
对象失效,再次调用evaluation...
方法则会弹出此错误信息
2、 其他错误信息(指纹系统判定有效,但是验证指纹错误):
LAErrorAuthenticationFailed : 鉴定失败
LAErrorUserCancel : 用户取消
LAErrorUserFallback : 用户选择输入密码
LAErrorSystemCancel : 系统取消(如:另外一个应用进入前台)

总结

上面分析了指纹识别的两种policy在不同系统上、不同状态下的各种响应状态,并且列出了一些指纹鉴定错误码,相信对整个API的作用有详尽的认识,开发出类似支付宝指纹识别的流程也不是难事,希望可以帮助更多人。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • 指纹识别: iPhone5S开始,推出指纹识别 iOS8.0之后苹果允许第三方 App 使用 Touch ID进行...
    a437e8f87a81阅读 1,341评论 0 17
  • 原文链接:http://yupeng.fun/2016/11/21/password/ 简介 苹果从iPhone5...
    MA806P阅读 6,399评论 10 74
  • 项目需要用到指纹识别,我把关键部分拿出来,代码如下: 引入头文件 指纹识别代码 调用test方法,就可以看到app...
    Hardy_Hu阅读 546评论 2 3
  • 你不知道 我最轻浅的念想 不过是和你一起仰望天堂 有你在的地方,就是天堂 我想,我们下辈子一定会遇到的 那时候,我...
    旧时光终究会老去阅读 326评论 0 1
  • 西风啸尽白马归, 古道树下空存灰 梵影清落自相随, 除却南尘犹未悔
    肖子安阅读 111评论 2 5