How to use Secure Enclave without TouchID and Passcode?

3.6k Views Asked by At

To generate key pair I am using Secure Enclave (kSecAttrTokenIDSecureEnclave). When trying to access generated key pair, iOS system, asks for TouchID. Below is code snapshot how I am generating and accessing key pair.

Is here a way to setup properties/attributes, that Secure Enclave functionality will be able to use without TouchID and Passcode?

Generate key pair:

SecAccessControlRef sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
                                                kSecAttrAccessibleWhenUnlocked,
                                                kSecAccessControlUserPresence | kSecAccessControlPrivateKeyUsage, &error);

    NSDictionary *parameters = @{
        (__bridge id)kSecAttrTokenID: (__bridge id)kSecAttrTokenIDSecureEnclave,
        (__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeEC,
        (__bridge id)kSecAttrKeySizeInBits: @256,
        (__bridge id)kSecPrivateKeyAttrs: @{
            (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject,
            (__bridge id)kSecAttrIsPermanent: @YES,
            (__bridge id)kSecAttrLabel: @“SecKey”,
        },
    };
SStatus status = SecKeyGeneratePair((__bridge CFDictionaryRef)parameters, &publicKey, &privateKey);

Access key pair:

    NSDictionary *query = @{
        (__bridge id)kSecClass: (__bridge id)kSecClassKey,
        (__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassPrivate,
        (__bridge id)kSecAttrLabel: @"SecKey",
        (__bridge id)kSecReturnRef: @YES
    };
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&privateKey);
1

There are 1 best solutions below

0
Ramis On BEST ANSWER

This code is taken form Apple examples KeychainTouchID. By removing kSecAccessControlTouchIDAny it is possible to generate private key inside secure enclave and later use it without entering a passcode.

SecAccessControlRef sacObject;

// Should be the secret invalidated when passcode is removed? If not then use `kSecAttrAccessibleWhenUnlocked`.
sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
                                            kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
                                            /*kSecAccessControlTouchIDAny |*/ kSecAccessControlPrivateKeyUsage, &error);

// Create parameters dictionary for key generation.
NSDictionary *parameters = @{
    (__bridge id)kSecAttrTokenID: (__bridge id)kSecAttrTokenIDSecureEnclave,
    (__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeEC,
    (__bridge id)kSecAttrKeySizeInBits: @256,
    (__bridge id)kSecPrivateKeyAttrs: @{
        (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject,
        (__bridge id)kSecAttrIsPermanent: @YES,
        (__bridge id)kSecAttrLabel: @"my-se-key",
    },
};