SecKeyCreateWithData returns nil in iOS 17

When I'm trying to create SecKey using SecKeyCreateWithData it returns nil in iOS 17 with following error:

Optional(Swift.Unmanaged<__C.CFErrorRef>(_value: Error Domain=NSOSStatusErrorDomain Code=-50 "EC private key creation from data failed" UserInfo={numberOfErrorsDeep=0, NSDescription=EC private key creation from data failed}))

guard let secKey = SecKeyCreateWithData(privateKey as CFData, attributes as CFDictionary, &error) else { print(error.debugDescription) throw EosioError(.keyManagementError, reason: error.debugDescription) }

It still working fine on iOS 16.4

  • I'm using these attributes:

    var attributes: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClass as String: kSecAttrKeyClassPrivate, kSecAttrKeySizeInBits as String: 256, kSecAttrAccessGroup as String: accessGroup, kSecAttrIsPermanent as String: true, kSecPrivateKeyAttrs as String: [ kSecAttrIsPermanent as String: true, kSecAttrAccessControl as String: access ] ]

  • privateKey is base64Encoded Data BNcHWtSeaQzOjwoHakZ66ojCFZV4uGU+VjRSAMOxd2NpwAEXHOarCV3yonOyJI5UIkJ1CCO+DbORtG83DDMkNuVmPGQu5nJiQCD9RfDA+UncG+woRrTrLDhAw6fHXD9DtA==

Add a Comment

Replies

I took your code and distilled it down to this:

let keyData: Data = .init([
    0x04,
    
    0xD7, 0x07, 0x5A, 0xD4, 0x9E, 0x69, 0x0C, 0xCE,
    0x8F, 0x0A, 0x07, 0x6A, 0x46, 0x7A, 0xEA, 0x88,
    0xC2, 0x15, 0x95, 0x78, 0xB8, 0x65, 0x3E, 0x56,
    0x34, 0x52, 0x00, 0xC3, 0xB1, 0x77, 0x63, 0x69,

    0xC0, 0x01, 0x17, 0x1C, 0xE6, 0xAB, 0x09, 0x5D,
    0xF2, 0xA2, 0x73, 0xB2, 0x24, 0x8E, 0x54, 0x22,
    0x42, 0x75, 0x08, 0x23, 0xBE, 0x0D, 0xB3, 0x91,
    0xB4, 0x6F, 0x37, 0x0C, 0x33, 0x24, 0x36, 0xE5,

    0x66, 0x3C, 0x64, 0x2E, 0xE6, 0x72, 0x62, 0x40,
    0x20, 0xFD, 0x45, 0xF0, 0xC0, 0xF9, 0x49, 0xDC,
    0x1B, 0xEC, 0x28, 0x46, 0xB4, 0xEB, 0x2C, 0x38,
    0x40, 0xC3, 0xA7, 0xC7, 0x5C, 0x3F, 0x43, 0xB4,
])
var errorQ: Unmanaged<CFError>? = nil
let keyQ = SecKeyCreateWithData(keyData as NSData, [
    kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
    kSecAttrKeyClass: kSecAttrKeyClassPrivate,
    kSecAttrKeySizeInBits: 256,
] as NSDictionary, &errorQ)

This works on iOS 16 but fails on iOS 17, with the error you mentioned above.

Note that this code doesn’t use the keychain, which confirms that the failure is with the EC key import than anything keychain related.

The most likely cause of this failure is an import check that we added in iOS 17 (r. 105458344). If you try to import an EC key whose point is not on the curve, iOS 17 fails the import with an error. On iOS 16 it would allow the import but then fail later on when you try to use the key. The new behaviour should make it easier for folks to track down the source of such ‘broken’ keys.

Note that Apple CryptoKit will also fail to import this key, but the error in that case is more confusing (.incorrectKeySize). We have a bug on file requesting that CryptoKit throw a better error (r. 115984576).

Share and Enjoy

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

I am facing the same issue. any update on this one ?