You can also get the same error (SecKeyCreate init(RSAPrivateKey) failed: -50
) from a RSA key if you:
Have not stripped the headers -----[BEGIN/END] PRIVATE KEY-----
from the .pem file contents
Loaded the file into string as a format other than ASCII (it's probably a common mistake to try to load it as UTF8)
Have not created a Data
object with the string using the base64Encoded
parameter (which will fail if you have loaded the file in a non-ASCII format)
So if you put all of this together, the full answer is this, which successfully creates the SecKey from a .key or .pem file (with .key, assuming you chose the correct options for public key):
let privateKeyData = try! Data(contentsOf: Bundle.main.url(forResource: "rsaPrivateKey", withExtension: "pem")!)
let privateKeyString = String(data: privateKeyData, encoding: .ascii)!
.replacingOccurrences(of: "-----BEGIN PRIVATE KEY-----", with: "")
.replacingOccurrences(of: "-----END PRIVATE KEY-----", with: "")
.replacingOccurrences(of: "\n", with: "")
let privateKeyStrippedData = Data(base64Encoded: publicKeyString, options: .ignoreUnknownCharacters)!
let options: [NSObject: NSObject] = [
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
kSecAttrKeySizeInBits: NSNumber(value: 2048)
]
var error: Unmanaged<CFError>?
let privateKey = SecKeyCreateWithData(privateKeyStrippedData as CFData, options as CFDictionary, &error)