Storing Secure Enclave Key into Keychain Service with Local Authentication Protection

Hi,

I'm currently trying to generate and store Private Key and protect this key with Local Authentication using Security framework (not CryptoKit; unfortunately, needed to support below iOS 13 still).

To be more precise, I am trying to generate Secure Enclave private key protected by local authentication (using access control with biometryAny), but I'm not able to trigger Local Authentication when retrieving the key. Secure Enclave key is successfully generated (that I confirmed), and I also confirmed that if I create a key without kSecAttrTokenID, exactly same code triggers the Local Authentication when reading the generated key.

Following is what I'm doing in my code:

// Key generation query
var query = [String: Any]()
query[String(kSecAttrKeyType)] = String(kSecAttrKeyTypeEC)
query[String(kSecAttrKeySizeInBits)] = 256
query[String(kSecAttrAccessGroup)] = "accessGroup"
query[String(kSecAttrTokenID)] = String(kSecAttrTokenIDSecureEnclave)
// Key Attributes
var keyAttr = [String: Any]()
keyAttr[String(kSecAttrIsPermanent)] = true
keyAttr[String(kSecAttrApplicationTag)] = "applicationTag"
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, .biometryAny, nil)!
keyAttr[String(kSecAttrAccessControl)] = accessControl
query[String(kSecPrivateKeyAttrs)] = keyAttr
// Generate Key
var error: Unmanaged<CFError>?
let privateKey = SecKeyCreateRandomKey(query as CFDictionary, &error)


If I remove "query[String(kSecAttrTokenID)] = String(kSecAttrTokenIDSecureEnclave)" this line of code which basically tells the system to generate the key using Secure Enclave, when retrieving the generated key, it triggers the Local Authentication, but with that Secure Enclave flag, Local Authentication is never triggered.

Is it not triggering the local authentication because the Secure Enclave key already protected with same level of security? or am I missing something here?

By the way, I tried with .userPresence and .biometryCurrentSet for Secure Enclave, but still had no luck.. :(

Any advice would be greatly appreciated.

Thanks,

Replies

We have same problem with enclave and biometry... and we did not find any information in documentation. Somebody with some experiences and skills? Is it a bug or a feature?

James G’s question probably came by when I was out of the office, so I never got a chance to clarify their requirements. However, I can respond to this:

we did not find any information in documentation

The standard techniques for this are covered by:

IME this stuff can be confusing [1] but it does actually work. If you clarify the specific problem you’re having, I’m happy to take a look.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Not helped by the fact that Storing Keys in the Secure Enclave missing a key point, namely that the keys aren’t stored in the SE but rather are protected by the SE. One day we’ll fix that (r. 83612073)-: