Is it possible?
The original key was generated and stored in the Keychain using the following code:
func generateSecureEnclaveProtectedSecKey(withTag tag: Data) throws -> SecKey {
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
[.privateKeyUsage],
&error
)!
let attributes = [
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits as String: 256,
kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave,
kSecPrivateKeyAttrs as String: [
kSecAttrCanSign as String: true,
kSecAttrIsPermanent as String: true,
kSecAttrApplicationTag as String: tag,
kSecAttrAccessControl as String: accessControl,
] as [String: Any],
] as [String: Any]
let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error)!
return privateKey
}
Then I wanted to use the strongly typed interface of CryptoKit, so I naively tried to get a hold of the existing key as follows (querying for kSecReturnPersistentRef
and not kSecReturnRef
):
func getSecureEnclaveProtectedCryptoKitKey(fromSecureEnclaveProtectedSecKeyWithTag tag: Data) throws -> SecureEnclave.P256.Signing.PrivateKey {
let query: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrApplicationTag as String: tag,
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecReturnPersistentRef as String: true,
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
let keyData = item as! CFData
return try SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: keyData as Data)
}
But that resulted in:
Error Domain=CryptoTokenKit Code=-3 "corrupted objectID detected" UserInfo={NSLocalizedDescription=corrupted objectID detected}
Since this is a Secure Enclave protected key, it is not possible to use SecKeyCopyExternalRepresentation (or query for kSecReturnData
), but perhaps there is another way to convert a SecKey object to a SecureEnclave.P256.Signing.PrivateKey?
The other way around seem to be possible using the answers to this blog post: https://developer.apple.com/forums/thread/728314
Is it possible to convert to and from a
SecureEnclave.P256.Signing.PrivateKey
object and aSecKey
object, both representing the same Secure Enclave protected key?
No. Or at least that’s my current understanding. You referenced this thread but I’ve since learnt more on another thread.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"