Reputation: 25
I'm trying to create a Private/Public key pair inside the SecureEnclave
with CryptoKit
and then save the reference to the private key in the KeyChain
for further usage. The key generation works totally fine:
let accessControl = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
[.privateKeyUsage],
nil
)!
let privateKey = try SecureEnclave.P256.Signing.PrivateKey(accessControl: accessControl)
// Describe the key.
let attributes = [
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeyClass: kSecAttrKeyClassPrivate
] as [String: Any]
But when I'm trying to convert the key I've just created into the SecKey
to store it in the Keychain later:
// Get a SecKey representation.
var error: Unmanaged<CFError>?
guard let secKey = SecKeyCreateWithData(key.dataRepresentation as CFData, attributes as CFDictionary, nil) else {
throw error!.takeRetainedValue()
}
It fails with an error:
The operation couldn’t be completed. (OSStatus error -50 - EC private key creation from data failed)
On the other hand, when I remove the SecureEnclave
element, and use the x963Representation
I'm capable of converting the private key into the SecKey
object:
let privateKey = P256.Signing.PrivateKey()
guard let secKey = SecKeyCreateWithData(privateKey.x963Representation as CFData, attributes as CFDictionary, nil) else {
throw error!.takeRetainedValue()
}
Any ideas on why this is happening or how can I fix this?
Upvotes: 2
Views: 1465
Reputation: 3264
Not all keys can be stored (directly) into the Keychain as described in the documentation. To resolve this, you can store raw Data
as generic password in the Keychain. It's a bit unfortunate for the SecureEnclave
keys.
In addition, the .dataRepresentation
of the Secure Enclave private key is not something the Security framework understands. Secure Enclave keys are not intended to be extracted (and as far as I know cannot be extracted at all). The blob you extract is a container that the same enclave can use to reconstruct the private key. Using the same data on another iPhone will not recreate the key.
I'm not sure if storing this blob as file on the device is a security risk. So I suggest you take a look at the previously mentioned documentation and use the GenericPasswordConvertible
example.
Upvotes: 2