Seckey from public key string from server in Swift

爱⌒轻易说出口 提交于 2019-12-03 15:14:30

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.

Here's how I did this:

let cert = SecCertificateCreateWithData(kCFAllocatorDefault, certData)?.takeRetainedValue()

if cert != nil {
    var trust: Unmanaged<SecTrust>?

    let policy = SecPolicyCreateBasicX509().takeRetainedValue()
    let status = SecTrustCreateWithCertificates(cert, policy, &trust)

    if status == errSecSuccess {
        let trustRef = trust!.takeRetainedValue()
        let key = SecTrustCopyPublicKey(trustRef)!.takeRetainedValue();
    }
}

This works, but you need to make sure that what you pass to SecCertificateCreateWithData() is a DER-encoded certificate, and not just a DER-encoded key. You need a certificate signed by your server's private key to the get the associated public key.

tinkl

I Did this used Alamofire:

private static func publicKeyForCertificate(certificate: SecCertificate) -> SecKey? {
    var publicKey: SecKey?
    var trust: Unmanaged<SecTrust>?

    let policy = SecPolicyCreateBasicX509().takeRetainedValue()
    let status = SecTrustCreateWithCertificates(certificate, policy, &trust)

    if status == errSecSuccess {
        let trustRef = trust!.takeRetainedValue()
        publicKey = SecTrustCopyPublicKey(trustRef)!.takeRetainedValue()

    }
    return publicKey

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!