Search code examples
iosswiftswift3public-key-encryptionseckeyref

Swift 3 export SecKey to String


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.


Solution

  • 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.