Objective-C ECDSA Signing and Verification, from .PEM, .DER or base64 string

Recently, i have been given a task to do digital signature on Elliptic Curve verification, and i found it is ridiculously hard to do in Swift.

My Situation is i have to verify a digital signature signed by Elliptic Curve with SHA-512, and the internet is completely lack of the support, which i spent a crazy amount of time to finally come up with a solution.

I have first tried to follow the Certificate, Key, and Trust Services Programming Guide at

;and also the library GMEllipticCurverCrypto at

and also the Apple CyptoExercise at

But none of this helped. The ECDSA signing and verification is ridiculously lack of support. Here is my quick solution and explanation with the use of openssl(which is already pre-installed in mac)

1. Generate a key (the curve prime256v1 will work, but secp256k1 WONT)

openssl ecparam -out eckey.pem -name prime256v1 -genkey

2. Generate a cert signing request from the key(the challenging password is for installing or re-installing the cert, but this is not case we concern here)

openssl req -new -key eckey.pem -out ecCertReq.csr

3. Sign the SSL Certificate

openssl x509 -req -days 365 -in ecCertReq.csr -signkey eckey.pem -out ecCert.crt

4. Create public key for iOS

openssl x509 -outform der -in ecCert.crt -out ec_public_key.de

5. Create private key for iOS(*pls remember the password here, it will be used for accessing this ec_private_key.p12)

openssl pkcs12 -export -out ec_private_key.p12 -inkey eckey.pem -in ecCert.crt

6. Create public key for Android

openssl ec -in eckey.pem -out ec_public_key.pem -pubout

7. Create private key for android

openssl pkcs8 -topk8 -in eckey.pem -out pkcs8_private_key.pem -nocrypt

So, you see that there are different key files. Short explanation

To create the SecKeyRef object for signing and verificaiton, you can direclt go for SecKeyCreateFromData(_:_:_:) which takes raw NSData from public key, but it is always fail. So we take the SecCertificateCreateWithData(_:_:), which takes raw NSData from the SSL cert we created. Go for the cert is way easier.

With the following two functions, getPublicKeyFromCertificate, we pass the public key, ec_public_key.der, getPrivateKeyReferenceFromData, we pass the private key, ec_private_key.p12

With functions to do signing and verification

and the signing and verification function

Another case, which is the normal case that you DON’T have the private key, and you just got the signature and public key.

You need the public key from the ec_cert.crt, with the following function

And then you can input the base64 string from the ecCert.crt
if you open it by cat or textEditor, you will see things like


which this base64 string can be converted to NSData and pass to the above — (SecKeyRef)getPublicKeyFromCertificate:(NSData *)data to get the public key

NSString *b64Cert = @”MIxxxxxxxxxxx”;
NSData *b64CertData= [[NSData alloc] initWithBase64EncodedString:b64Cert options:NSDataBase64DecodingIgnoreUnknownCharacters];
SecKeyRef publicKey = [self getPublicKeyFromCertificate:b64CertData];

Done! So, no matter you are given the key files(.der for public, .p12 for private), or just a base64 string from a SSL certificate, you can now verify the Elliptic Curve signed signature.

At the end, i would like to have some explanation on the key files we created.

The cert we created(ecCert.crt) is a SSL cert, which you install in your server, and means that your server can be trusted, the browser will then instantiate a https connection. More info at

You can see that there are different format of keys, .der, .pem, .p12 If you open them in textEditor, or with cat. You can see that both .der and .p12 are encoded while .pem is in base64 string.

For the SSL certificates, it has to be in x509 format, which the format is in ASN.1 data structure.

.der means DER encoded certificate
.p12 means PKCS #12, which format the key under Public Key Cryptography Standard #12
.pem which is a base64 encoded .der file

Just bear in mind, the most convenient way for getting a SecKeyRef object in iOS will be having a .der file for public key, .p12 file for private key.

For Java, it is the .pem for both public and private key.


Playing with Swift Digital Signature Signing and Verfication