Search code examples
iosswiftpublic-key-encryptionencryption-asymmetricseckeyref

Seckey from public key string from server in Swift


I want to encrypt data using RSA , I tried to generate the key in my code and it's working , But what I actually need is to get the public key as a string from server and then use it as Seckey so I can use it to encrypt data using RSA, I tried this code:

//KeyString is the string of the key from server
let KeyData = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!


    var cert : Unmanaged<SecCertificateRef>!;
    var  policy : Unmanaged<SecPolicy>!;
    cert = SecCertificateCreateWithData(kCFAllocatorDefault, KeyData);
    policy = SecPolicyCreateBasicX509();
    var status : OSStatus = noErr
    var trust: SecTrust?
    var certArray : [Unmanaged<SecCertificateRef>!] = [cert];
    var certArrayPointer = UnsafeMutablePointer<UnsafePointer<Void>>(certArray)
    status = SecTrustCreateWithCertificates(cert, policy, trust);
    let publicKey: SecKeyRef = SecTrustCopyPublicKey(trust!).takeUnretainedValue()

I couldn't run this code because SecTrustCreateWithCertificates Method is expecting certificate as anyObject! , I don't Know how to fix this,And if solving this will let me get the SecKey.

I got the code above from this answer in objective-c

So if any one can help me getting the right code to solve this , I will be very thankful :)


Solution

  • For mac:

    let pubKey = "-----BEGIN PUBLIC KEY-----MIICIjANBgAgK.......InbFk1FkucQqruMyUCAwEAAQ==-----END PUBLIC KEY-----"
    let pubKeyData = pubKey.dataUsingEncoding(NSASCIIStringEncoding)
    var error: Unmanaged<CFErrorRef>?
    let secKey = SecKeyCreateFromData(NSDictionary(), pubKeyData!, &error)
    

    Where pubKey is a string representation of your public key. If you don't know your public key, you can infer it from your private key with the following command:

    openssl rsa -in server.key -pubout  > mykey.pub
    

    Where server.key is the file containing -----BEGIN RSA PRIVATE KEY----- as the first line.

    For iOS:

    It's a bit more complicate. You need a der file. It's a binary representation of your certificate. If you need to convert an existing certificate, you can do so with the following command:

     openssl x509 -outform der -in file.crt|pem -out mycert.der
    

    The .crt or .pem file contains -----BEGIN CERTIFICATE----- as the first line.

    Put the der file in your bundle and do:

    let certificateData = NSData(contentsOfURL:NSBundle.mainBundle().URLForResource("mycert", withExtension: "der")!)
    
    let certificate = SecCertificateCreateWithData(nil, certificateData!)
    
    var trust: SecTrustRef?
    
    let policy = SecPolicyCreateBasicX509()
    let status = SecTrustCreateWithCertificates(certificate!, policy, &trust)
    
    if status == errSecSuccess {
        let key = SecTrustCopyPublicKey(trust!)!;
    }
    

    Yatta ! Key now contains a SecKey representation of your public key. Happy Pinning.