When your mobile application is communicating with SSL servers, you can heighten the security by implementing SSL pinning, which prevents man-in-the-middle attacks and ensures that third parties cannot read and intercept private data about your user.

The most common approach for implementing SSL pinning on iOS is pinning the certificate as a whole (see the sample code provided by OWASP). The problem with this approach is that every time the certificate needs to be updated (which can happen for various reasons, such as when the encryption algorithm changes or the certificate is compromised), your app will need an update. This poses serious issues because you could potentially abandon all users who did not or will not update the app.

Another alternative to pinning the certificate as a whole is to pin the public key of the root certificate in the certificate’s chain; this keeps the security intact while solving the problem of handling new certificates. Unfortunately, Apple’s iOS APIs within the Security Framework don’t play well with this approach.

It is possible to pin the public key of the whole certificate using

This is how popular frameworks such as AFNetworking and AlamoFire are implemented, but this does not solve our problem. We are looking to pin only the public key of the root certificate (which is in the certificate’s chain), not the whole certificate. The public key of the whole certificate is more likely to chain between certificate changes/updates. You can retrieve the root certificate, but not its public key.

A solution, though not the cleanest, is to extract the public key of the root certificate using a library on GitHub called ios-openssl. By extracting the public key, and comparing it with the public key from the SSL certificate that you are using to pin, we have found the solution to our problems.

This is a workaround, though, and Apple should provide us an easy way to do this using the iOS Security.Framework. I would plead that you file a bug report so this catches Apple’s attention!

Share Button
  • m3kw

    So the Public Key stays the same even after updating the Certificate?

  • Nabla

    We have released an open-source SSL pinning library for iOS that makes it super easy to deploy pinning within an App: https://github.com/datatheorem/TrustKit

    It uses a different workaround for extracting the public key, by leveraging the Keychain. This allows the library to not have OpenSSL as a (rather huge) dependency.