Swift 3 export SecKey to String
Asked Answered
K

1

9

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.

Keelboat answered 27/4, 2017 at 22:59 Comment(3)
Can you get the SecKey` as Data? Once you have Data, getting a base64 string is easy.Tubule
Do you really need to use that tricky SecKey class of yours? After reading this detailed question I don't think there is an easy hack around this :-(Anemometry
@PauloMattos unfortunately, yes. The cryptographic libraries I am using require a SecKey object, as I am generating those keys from the app.Keelboat
B
24

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://mcmap.net/q/504153/-how-do-i-encode-an-unmanaged-lt-seckey-gt-to-base64-to-send-to-another-server and https://mcmap.net/q/1170947/-how-do-i-export-a-public-key-lt-seckey-gt-that-was-generated-using-seckeygeneratepair-to-be-used-on-a-server 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.

Berar answered 28/4, 2017 at 8:17 Comment(6)
I'm going to try that tomorrow. On the reimport, is cfdata the base64 string ?Keelboat
oops. Sorry. I was lazy and didn't bother generating Data from String and CFData from Data. Can you handle that? Otherwise I'll try and add the code later today.Berar
Never mind. I've just edited the code. Damn the 5 minute limit on comments!Berar
Thank you, it works for exporting public key string, and I reuse it for exporting private key as well.Apostles
There is also the official documentation by Apple for converting between SecKey and Data: developer.apple.com/documentation/security/…Vickyvico
@Vickyvico this question is six years old. As the one who answered the question, I don't recall this documentation existing back then. Also, swift was rapidly evolving back then. IIRC, Swift 2 was very different from 3. Things only slowed down in versions 4 and 5.Berar

© 2022 - 2024 — McMap. All rights reserved.