Swift 3 export SecKey to String

Scaraux picture Scaraux · Apr 28, 2017 · Viewed 8.9k times · Source

I am developing an iOS app using swift 3.

I need to export an SecKey (which is the user RSA publickey reference) to a string (e.g base64) in order to share it through a generated QRCode.

It also has to work the other way since the other user that scans the QRCode, will be able to rebuild a SecKey reference from the string extracted from the QRCode.

I found few tutorials but I don't understand exactly what I need to extract from the SecKey reference, and I don't know how to convert it to a String.

Answer

Roy Falk picture Roy Falk · Apr 28, 2017

Export Key (iOS 10 only)

var error:Unmanaged<CFError>?
if let cfdata = SecKeyCopyExternalRepresentation(publicKey!, &error) {
   let data:Data = cfdata as Data
   let b64Key = data.base64EncodedString()
}

See https://stackoverflow.com/a/30662270/5276890 and https://stackoverflow.com/a/27935528/5276890 for longer ways which probably support iOS < 10.

Reimport Key

guard let data2 = Data.init(base64Encoded: b64Key) else {
   return
}

let keyDict:[NSObject:NSObject] = [
   kSecAttrKeyType: kSecAttrKeyTypeRSA,
   kSecAttrKeyClass: kSecAttrKeyClassPublic,
   kSecAttrKeySizeInBits: NSNumber(value: 512),
   kSecReturnPersistentRef: true as NSObject
]

guard let publicKey = SecKeyCreateWithData(data2 as CFData, keyDict as CFDictionary, nil) else {
    return
}

Note: This generates a base64 key and not a certificate. A lot of code samples online deal with how to generate a public key from a certificate using SecCertificateCreateWithData

Also: 512 bit is fast to generate but worthless. Pick a longer and secure value once you're satisfied with the results.

I got valid results back when importing the key I generated and exported, so I assume it works, but I did not try to encrypt and decrypt with it.