安全性
开启指纹支付的必须满足以下安全条件:
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(@"为了安全支付环境, 越狱手机禁止使用指纹支付");
}
}