检测当前设备上是否有Secure Enclave可用

是否有某种方法可以检测当前设备上是否存在Secure Enclave存储?

我自己做的:

+ (BOOL) isDeviceOkForSecureEnclave { double OSVersionNumber = floor(NSFoundationVersionNumber); UIUserInterfaceIdiom deviceType = [[UIDevice currentDevice] userInterfaceIdiom]; BOOL isOSForSecureEnclave = OSVersionNumber > NSFoundationVersionNumber_iOS_8_4 ? YES:NO; //iOS 9 and up are ready for SE BOOL isDeviceModelForSecureEnclave = NO; switch (deviceType) { case UIUserInterfaceIdiomPhone: //iPhone isDeviceModelForSecureEnclave = [self isPhoneForSE]; break; case UIUserInterfaceIdiomPad: //iPad isDeviceModelForSecureEnclave = [self isPadForSE]; break; default: isDeviceModelForSecureEnclave = false; break; } return (isOSForSecureEnclave && isDeviceModelForSecureEnclave) ? YES:NO; } /** The arrays are models that we know not having SE in hardware, so if the current device is on the list it means it dosent have SE */ + (BOOL) isPhoneForSE { NSString *thisPlatform = [self platform]; NSArray * oldModels = [NSArray arrayWithObjects: @"x86_64", @"iPhone1,1", @"iPhone1,2", @"iPhone2,1", @"iPhone3,1", @"iPhone3,3", @"iPhone4,1", @"iPhone5,1", @"iPhone5,2", @"iPhone5,3", @"iPhone5,4", nil]; BOOL isInList = [oldModels containsObject: thisPlatform]; return !isInList; } + (BOOL) isPadForSE { //iPad Mini 2 is the earliest with SE // "iPad4,4" NSString *thisPlatform = [self platform]; NSArray * oldModels = [NSArray arrayWithObjects: @"x86_64", @"@iPad", @"@iPad1,0", @"@iPad1,1", @"iPad2,1", @"iPad2,2", @"iPad2,3", @"iPad2,4", @"iPad2,5", @"iPad2,6", @"iPad2,7", @"iPad3,1", @"iPad3,2", @"iPad3,3", @"iPad3,4", @"iPad3,5", @"iPad3,6",nil]; BOOL isInList = [oldModels containsObject: thisPlatform]; return !isInList; } + (NSString *)platform { size_t size; sysctlbyname("hw.machine", NULL, &size, NULL, 0); char *machine = malloc(size); sysctlbyname("hw.machine", machine, &size, NULL, 0); NSString *platform = [NSString stringWithUTF8String:machine]; free(machine); return platform; } @end 

这是另一个解决方案:

device.h中

 #import  @interface Device : NSObject +(BOOL) hasSecureEnclave; +(BOOL) isSimulator; +(BOOL) hasBiometrics; @end 

Device.m

 #import "Device.h" #import  @implementation Device //To check that device has secure enclave or not +(BOOL) hasSecureEnclave { NSLog(@"IS Simulator : %d", [Device isSimulator]); return [Device hasBiometrics] && ![Device isSimulator] ; } //To Check that this is this simulator +(BOOL) isSimulator { return TARGET_OS_SIMULATOR == 1; } //Check that this device has Biometrics features available +(BOOL) hasBiometrics { //Local Authentication Context LAContext *localAuthContext = [[LAContext alloc] init]; NSError *error = nil; /// Policies can have certain requirements which, when not satisfied, would always cause /// the policy evaluation to fail - eg a passcode set, a fingerprint /// enrolled with Touch ID or a face set up with Face ID. This method allows easy checking /// for such conditions. BOOL isValidPolicy = [localAuthContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]; if (isValidPolicy) { if (@available(ios 11.0, *)){ if (error.code != kLAErrorBiometryNotAvailable){ isValidPolicy = true; } else{ isValidPolicy = false; } }else{ if (error.code != kLAErrorTouchIDNotAvailable){ isValidPolicy = true; }else{ isValidPolicy = false; } } return isValidPolicy; } return isValidPolicy; } @end 

如果您想在Swift 4中使用解决方案,请参阅此链接。

Swift 4中的解决方案

对于开发人员来说,Secure Enclave可以做的事情就是:为椭圆曲线加密创建和保存私钥,并使用这些密钥加密或解密数据。 在iOS 9上,描述椭圆曲线算法的属性不存在 – 因此,如果您运行的是iOS 9,那么您可以假设Secure Enclave不存在,因为您无法使用它。

在iOS 10及更高版本中,如果Secure Enclave存在,只有一种方法可以正确地确定:在Apple Encocve中创建一个椭圆曲线加密密钥,如Apple的文档所述。 如果失败,并且错误的代码为-4 = secErrUnimplemented,那么就没有Secure Enclave。

如果您坚持要检查设备列表,则只需要记录为没有Secure Enclave但​​能够运行iOS 10的设备,因为在iOS 9上它永远不可用。