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

时间:2017-01-20 09:19:12

标签: ios security

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

4 个答案:

答案 0 :(得分:1)

这是另一种解决方案:

<强> device.h中

extension UIViewController {
    func prefersStatusBarHidden() -> Bool {
        return true
    }
}

<强> Device.m

#import <Foundation/Foundation.h>

@interface Device : NSObject

+(BOOL) hasSecureEnclave;
+(BOOL) isSimulator;
+(BOOL) hasBiometrics;

@end

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

Solution in Swift 4

答案 1 :(得分:1)

对于开发人员而言,Secure Enclave完全可以做一件事:创建和保存用于椭圆曲线加密的私钥,并使用这些密钥对数据进行加密或解密。在iOS 9上,不存在描述椭圆曲线算法的属性-因此,如果您正在运行iOS 9,则可以假定Secure Enclave不存在,因为您无法使用它。

在iOS 10及更高版本上,只有一种方法可以正确确定是否存在安全保护区:如Apple文档所述,在安全保护区中创建椭圆曲线加密密钥。如果失败,并且错误代码为-4 = secErrUnimplemented,则没有安全区域。

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

答案 2 :(得分:0)

我自己做了:

+ (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

答案 3 :(得分:0)

有一种更直接的方法可以使用 CryptoKit 框架检查 Secure Enclave 是否可用。以下方法仅适用于 iOS 13+ 和 Swift。

import CryptoKit

if TARGET_OS_SIMULATOR == 0 && SecureEnclave.isAvailable {
    // use Secure Enclave
}

需要额外检查模拟器,因为 SecureEnclave.isAvailable 返回在模拟器上运行的 true(在 iOS 14.4 上检查)。