ios支付安全 指纹支付

作者: HeavenWong | 来源:发表于2017-03-07 11:54 被阅读159次

    安全性

    开启指纹支付的必须满足以下安全条件:
    • 1 . 开启指纹支付, 需读完指纹支付协议, 验证交易密码, 才可以开启指纹支付

    • 2 . 判断是否是越狱手机, 越狱手机禁止开启指纹支付

    • 3 . 指纹识别功能是iphone 5S之后推出的.SDK是iOS 8.0推出! 判断只有ios8以上的系统才可以使用

    • 4 . 获取 手机用户UUID, 避免不同设备登录. 判断设备登录(可以换种方式判断: 用户第一次使用判断是否开启了指纹支付,存本地)

        指纹识别功能是iphone 5S之后推出的.SDK是iOS 8.0推出!
      
        推出指纹识别功能的目的,是为了简化移动支付环节,占领移动支付市场.
      
        虽然安装iOS 7系统的5s机型可以使用系统提供的指纹解锁功能,但由于API并未开放,所以理论上第三方软件不可使用。
      
        指纹验证功能的最低硬件支持为iPhone5s,iPad 6,iPad mini 3这些有touch ID硬件支持的设备。
      

    判断手机是否越狱

    1. 判定常见的越狱文件
      /Applications/Cydia.app
    
      /Library/MobileSubstrate/MobileSubstrate.dylib
    
      /bin/bash
    
      /usr/sbin/sshd
    
      /etc/apt
    
      这个表可以尽可能的列出来,然后判定是否存在,只要有存在的就可以认为机器是越狱了。
    
    #define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])  
      
    const char* jailbreak_tool_pathes[] = {  
        "/Applications/Cydia.app",  
        "/Library/MobileSubstrate/MobileSubstrate.dylib",  
        "/bin/bash",  
        "/usr/sbin/sshd",  
        "/etc/apt"  
    };  
      
    - (BOOL)isJailBreak  
    {  
        for (int i=0; i<ARRAY_SIZE(jailbreak_tool_pathes); i++) {  
            if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:jailbreak_tool_pathes[i]]]) {  
                NSLog(@"The device is jail broken!");  
                return YES;  
            }  
        }  
        NSLog(@"The device is NOT jail broken!");  
        return NO;  
    } 
    
    2. 判断cydia的URL scheme
      URL scheme是可以用来在应用中呼出另一个应用,是一个资源的路径(详见《iOS中如何呼出另一个应用》),这个方法也就是在判定是否存在cydia这个应用。
    
    - (BOOL)isJailBreak  
    {  
        if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://"]]) {  
            NSLog(@"The device is jail broken!");  
            return YES;  
        }  
        NSLog(@"The device is NOT jail broken!");  
        return NO;  
    }  
    
    
    3. 读取系统所有应用的名称
    这个是利用不越狱的机器没有这个权限来判定的。
    
    #define USER_APP_PATH                 @"/User/Applications/"  
    - (BOOL)isJailBreak  
    {  
        if ([[NSFileManager defaultManager] fileExistsAtPath:USER_APP_PATH]) {  
            NSLog(@"The device is jail broken!");  
            NSArray *applist = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:USER_APP_PATH error:nil];  
            NSLog(@"applist = %@", applist);  
            return YES;  
        }  
        NSLog(@"The device is NOT jail broken!");  
        return NO;  
    }  
    
    4. 使用stat方法来判定cydia是否存在
      这个方法本身思路还是通过判定cydia应用,但方法是用的stat函数,同时会判定是否有注入动态库。
    
    #define CYDIA_APP_PATH                "/Applications/Cydia.app"  
    int checkInject()  
    {  
        int ret;  
        Dl_info dylib_info;  
        int (*func_stat)(const char*, struct stat*) = stat;  
          
        if ((ret = dladdr(func_stat, &dylib_info)) && strncmp(dylib_info.dli_fname, dylib_name, strlen(dylib_name))) {  
            return 0;  
        }  
        return 1;  
    }  
      
    int checkCydia()  
    {  
        // first ,check whether library is inject  
        struct stat stat_info;  
          
        if (!checkInject()) {  
            if (0 == stat(CYDIA_APP_PATH, &stat_info)) {  
                return 1;  
            }  
        } else {  
            return 1;  
        }  
        return 0;  
    }  
      
    - (BOOL)isJailBreak  
    {  
        if (checkCydia()) {  
            NSLog(@"The device is jail broken!");  
            return YES;  
        }  
        NSLog(@"The device is NOT jail broken!");  
        return NO;  
    }  
    
    5. 读取环境变量
      这个DYLD_INSERT_LIBRARIES环境变量,在非越狱的机器上应该是空,越狱的机器上基本都会有Library/MobileSubstrate/MobileSubstrate.dylib
    
    char* printEnv(void)  
    {  
        charchar *env = getenv("DYLD_INSERT_LIBRARIES");  
        NSLog(@"%s", env);  
        return env;  
    }  
      
    - (BOOL)isJailBreak  
    {  
        if (printEnv()) {  
            NSLog(@"The device is jail broken!");  
            return YES;  
        }  
        NSLog(@"The device is NOT jail broken!");  
        return NO;  
    }  
    
    当然,判定一个设备是否越狱时,可以多种方法并用以确保准确。这里我还想说的是越狱有完美越狱还有非完美越狱,这本身就不是官方有保证的行为,所以情况也是复杂多变。iOS7针对沙盒机制也有了改进升级,有些情况对新的版本或许是不合适的,这点还需要实际情况实际处理。

    指纹支付核心代码

    方案

    • 首先导入头文件#import <LocalAuthentication/LocalAuthentication.h>

        #import <LocalAuthentication/LocalAuthentication.h>
      
    • 在application里面实现

    
    #define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])  
      
    const char* jailbreak_tool_pathes[] = {  
        "/Applications/Cydia.app",  
        "/Library/MobileSubstrate/MobileSubstrate.dylib",  
        "/bin/bash",  
        "/usr/sbin/sshd",  
        "/etc/apt"  
    };  
     // yes == 越狱机, no == 非越狱
    - (BOOL)isJailBreak  
    {  
        for (int i=0; i<ARRAY_SIZE(jailbreak_tool_pathes); i++) {  
            if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:jailbreak_tool_pathes[i]]]) {  
                NSLog(@"The device is jail broken!");  
                return YES;  
            }  
        }  
        NSLog(@"The device is NOT jail broken!");  
        return NO;  
    } 
    
    - (void)setFingerprint{
    
    // 1. 判断是否是越狱手机
    if(![self isJailBreak]){
    
    // 2 . iOS 8及以上版本执行-(void)authenticateUser方法,方法自动判断设备是否支持和开启Touch ID
        if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
            NSLog(@"你的系统满足条件");
            // 3 . 是否开启指纹支付 && 是否已登录
            if ([JCCore getFingerprint] && [JCCore is_login]) {
            UIView *v = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds ];
            v.backgroundColor = [UIColor yellowColor];
    
            //创建LAContext
            LAContext *context = [LAContext new];
            //这个属性是设置指纹输入失败之后的弹出框的选项
            context.localizedFallbackTitle = nil;
            NSError *error = nil;
            // 4 . 是否支持指纹
            if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                  [_window addSubview:v];
                  // 切换到主线程处理
                }];
                NSLog(@"支持指纹识别");
                [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"需要验证您的指纹来确认您的身份" reply:^(BOOL success, NSError * _Nullable error) {
                    if (success) {
                        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                          [v removeFromSuperview];
                        }];
                        [v removeFromSuperview];
                        NSLog(@"验证成功 刷新主界面 %@",[JCCore get_employee_info]);
    
                    }else {
                        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                         // 切换到主线程处理
                            [v removeFromSuperview];
                            [JCCore quitOut];
                             [self go_login];
                        }];
    
                        NSLog(@"%@",error.localizedDescription);
                        switch (error.code) {
                            case LAErrorSystemCancel:
                            {
                                NSLog(@"系统取消授权,如其他APP切入");
                                break;
                            }
                            case LAErrorUserCancel:
                            {
    
                                NSLog(@"用户取消验证Touch ID");
                                break;
                            }
                            case LAErrorAuthenticationFailed:
                            {
                                NSLog(@"授权失败,请手动登录");
                                break;
                            }
                            case LAErrorPasscodeNotSet:
                            {
                                NSLog(@"系统未设置密码");
                                break;
                            }
                            case LAErrorTouchIDNotAvailable:
                            {
                                NSLog(@"设备Touch ID不可用,例如未打开");
                                break;
                            }
                            case LAErrorTouchIDNotEnrolled:
                            {
                                NSLog(@"设备Touch ID不可用,用户未录入");
                                break;
                            }
                            case LAErrorUserFallback:
                            {
                                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                    NSLog(@"用户选择输入密码,切换主线程处理");
                                }];
                                break;
                            }
                            default:
                            {
                                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                    NSLog(@"其他情况,切换主线程处理");
                                }];
                                break;
                            }
                        }
                    }
                }];
            }else{
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                 // 切换到主线程处理
                    [v removeFromSuperview];
                    [JCCore quitOut];
                    [self go_login];
                }];
                NSLog(@"不支持指纹识别");
                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;
                    }
                }
    
                NSLog(@"%@",error.localizedDescription);
            }
    
        }
        }else {
            NSLog(@"你的系统版本太低, 不能使用指纹支付");
        }
        }else {
        NSLog(@"为了安全支付环境, 越狱手机禁止使用指纹支付");
        }
        
    }
    
    

    参考原文作者

    相关文章

      网友评论

        本文标题:ios支付安全 指纹支付

        本文链接:https://www.haomeiwen.com/subject/grrugttx.html