Определите, доступен ли Secure Enclave на текущем устройстве

Есть ли определенный способ определить, доступно ли сохранение в Secure Enclave на текущем устройстве?

4 ответа

Вот еще одно решение:

device.h

#import <Foundation/Foundation.h>

@interface Device : NSObject

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

@end

Device.m

#import "Device.h"
#import <LocalAuthentication/LocalAuthentication.h>

@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 - e.g. 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: создайте ключ шифрования эллиптической кривой в Secure Enclave, как описано в документации Apple. Если это не удается, и ошибка имеет код -4 = secErrUnimplemented, тогда Secure Enclave не существует.

Если вы настаиваете на проверке списка устройств, вам нужны только те устройства, для которых задокументировано, что они не имеют безопасного анклава, но могут работать с iOS 10, потому что в iOS 9 оно никогда не доступно.

Я сам это сделал:

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

Существует более простой способ проверить, доступен ли Secure Enclave, используя инфраструктуру CryptoKit. Следующий подход предназначен только для iOS 13+ и Swift.

      import CryptoKit

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

Требуется дополнительная проверка симулятора, т.к. SecureEnclave.isAvailableвозвращается trueработает на Симуляторе (проверено на iOS 14.4).

Другие вопросы по тегам