Search code examples
swiftopensslrsapemder

PEM encoded certificate conversion in iOS


In my app I get a PEM encoded certificate and need to convert it into a different form to later use it for JWT verification purposes. The result I'm looking for is either a SecKey representation of the public key contained in the certificate, PEM Public Key string or conversion to a DER certificate.

I am very VERY new to this, so I have no idea how to tackle the problem. I've Googled around and found no clear solution, even Apple documentation only mentions DER certificates. If I understand it correctly, one solution would be to use OpenSSL inside my app (is this even possible?) for conversions, but I couldn't find any useful resource on how to implement this so I would appreciate more insight on the right practice.

Making conversions outside the application is not an option for my case.


Solution

  • If you have a certificate in PEM format, you can obtain it's DER encoded data by stripping away the header and footer lines and base64-decoding the text in between them (don't forget to discard line breaks as well). [1, 2]

    You can then use SecCertificateCreateWithData from the iOS Security API to create a SecCertificate to use in your app like so:

    // example data from http://fm4dd.com/openssl/certexamples.htm
    let pem = """
        -----BEGIN CERTIFICATE-----
        MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG
        (...)
        +tZ9KynmrbJpTSi0+BM=
        -----END CERTIFICATE-----
        """
    
    // remove header, footer and newlines from pem string
    
    let certData = Data(base64Encoded: pemWithoutHeaderFooterNewlines)!
    
    guard let certificate = SecCertificateCreateWithData(nil, data as CFData) else {
        // handle error
    }
    
    // use certificate e.g. copy the public key
    let publicKey = SecCertificateCopyKey(certificate)!
    

    [1]

    PEM format is simply base64 encoded data surrounded by header lines.

    [2]

    .pem – Base64 encoded DER certificate, enclosed between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"