In this blog we introduce our new mobile certificate pinning configuration tool. This free web tool allows you to automatically generate the configuration required to pin your mobile app connections, providing an additional layer of security.
Certificate pinning, with support for dynamic updates, has long been a part of Approov. However, we are committed to improving security across the industry and are therefore providing this tool as a contribution to the community.
Certificate pinning is the mechanism of an app associating a domain name with one or more expected TLS certificates. More precisely, the mechanism discussed here is Subject Public Key Identity (SPKI) pinning where a particular public key used by a certificate is pinned.
Whenever the app needs to establish a connection with the server hosting that domain name a TLS handshake takes place. This handshake establishes trust based on the certificate chain presented. Ultimately the chain must lead to a certificate authority that has been installed in the trust store of the device.
This means, though, that your app is effectively outsourcing its trust to the device on which it is running and the trust store that it has. If any of the certificate authorities becomes compromised, or issues certificates without sufficient verification, then it is possible for your backend server to be impersonated. Such an impersonation could be executed, for instance, on a public network if the DNS can be poisoned or misdirected to point at an attacker’s server with a compromised certificate. In this case your app would happily connect with such a server, believing it to be the official one. This would of course put your customers’ data at risk.
Pinning adds an additional restriction into the TLS connection process. In addition to all the usual checks, the certificate chain must also include one or more certificate public keys within it that have been specifically identified as belonging to your service. This provides an additional level of security so your app is no longer just dependent on the trust store of the end user device.
An additional benefit of certificate pinning is that it also makes your app’s operations more difficult to reverse engineer. It is common practice for an attacker to use a Man-in-the-Middle (MitM) proxy tool to observe the traffic between your app and backend servers in order to understand the API, perhaps to subsequently launch an attack against it. We covered this in our recent blog “How to MitM Attack the API of an Android App”. So even if you believe you have obfuscated and hidden secrets in the code of your app, they might still be easily revealed with a MitM proxy tool. Be aware though, that if an attacker controls the end device that the app is running on then it is still be possible to do a MitM as we discuss in our blog “How to Bypass Certificate Pinning with Frida on an Android App”. Pinning does make this considerably more difficult though. If you want even greater protection then you should consider using Approov.
In the past, implementing certificate pinning has been somewhat complex and very dependent on the networking stack being used. DataTheorem’s TrustKit has always been a great package for implementing it, especially on iOS. In recent years, however, Google and Apple have built support directly into their platforms to make the whole process easier, and less dependent on the networking stack being used.
Google has supported pinning since Android 7, see the Network Security Configuration documentation. Pins just need to be specified in the particular XML format of that file. More recently, Apple has also jumped on board with NSPinnedDomains support from iOS 14. Pins just need to be added in the correct format to the Info.plist file for the app. See their blog on Identity Pinning that discusses some of the setup.
So there is now some good platform support, but the configuration part remains complex - especially if you are not well versed in the dark arts of PKI and certificate management. Much of the setup relies on invoking some quite convoluted openssl commands and managing certificate files in various formats.
We thought this part could be improved to ease the adoption, and we had already built some technology in Approov for this, so we decided to open its use up to the wider community.
One feature of our Approov solution is that it makes it easier to manage certificate pinning in mobile apps. We primarily manage this server side (which provides the advantage of over-the-air updates, which we’ll discuss later). We’ve opened up some of this and built a simple web page to allow you to generate pinning configurations really easily.
You can access the tool here and there is no need to sign up to use it. You are presented with a form like this:
You just need to enter the domains that you want to pin and press the “Submit” button, and the tool will automatically generate the exact configuration needed.You can then copy and paste into your Android or iOS app to implement the pinning. There are detailed instructions on all the columns if you click the information buttons.
Pinning is performed on a whole domain (a hostname, without the https prefix) rather than specific endpoint URI paths.
If you want to pin more than a single domain then just click “Add Another Domain” to provide the details for others. The page supports up to 10.
With the tool you can easily extract pins from the live certificates being presented on particular endpoints. Once you’ve pressed “Submit” you will get something like this.
This is for our example domain “shapes.approov.io”. You’ll see the pins for the entire certificate chain presented on the endpoint, with expiry and name information for the presented certificates.
The probing of the endpoint is actually done from our servers, so the domain does need to be live on the Internet or else you will receive an error.
Be aware that you should only be pinning against endpoints that you or your team/company are in control of, so that you will know when the certificate pins might need to be changed.
If you click on the Android tab then you can see the XML file produced for Android that you can simply copy and paste into your app to implement the pinning. Full instructions are provided on the page.
For Android, the expiration date is included automatically based on the earliest expiration date of any of the pins. If you know that the same pins will be retained even after the current certificates are renewed then you don’t need this and it can be removed.
You’ll see that in this example it is the leaf certificate pin that is included, because that option is ticked by default on the configuration page. This pins to the certificate presented by the server itself. Alternatively you can select the “Pin Root Certificate” option instead to pin to the Certificate Authority at the top of the trust chain. Although no option is provided directly to pin to an intermediate you can easily copy and paste a pin from the “Results” tab and manually include that in your configuration.
Similar information is provided in the iOS tab, but in the slightly different format that it needs.
It’s really that simple and straightforward to generate the pinning configuration you need. You should test that it’s working though. This is mostly easily done by temporarily changing the pins so that they don’t match, and checking that the app is indeed no longer able to make connections.
The risk with certificate pinning is what happens if the pins change and no longer match those expected by the app. The app will no longer be able to make connections to the backend and you can end up with a lot of unhappy users. Implementing static certificate pinning really does require care and attention. We’ve described many of the pitfalls on the FAQ tab on the tool page.
Such a situation might be caused by a misunderstanding or miscommunication between the frontend or backend teams. Or perhaps the certificate has been compromised and there is a need to change it in a hurry. However, in order to change the pins you are going to have to release a new version of the app and your users must update to it. That takes time and will generate a lot of user friction.
This is why it is really important that you also include at least one backup pin as well as the ones that are currently live on the endpoints. This backup pin can be extracted from an alternative certificate that is valid for the domain. The idea is that if there is some emergency situation which requires the new certificate to be presented then your app will already be set up to accept it with no changes, and no downtime.
Adding a backup pin is easy, just select the locally stored certificate file for the domain and it will also be included as a pin. Checks will be made that the certificate is valid for the domain and hasn’t already expired.
We realise that certificate file formats are a little arcane. The tool accepts .cer, .crt and .der extension files and does its best to decode the format automatically. Both PEM encoded ASCII files and DER encoded binary files are acceptable. You only need to provide the file with the certificate and its public key. We detect if you accidentally provide a private key and ensure that this never leaves your browser.
You can also use the certificate file feature if you want to include a pin that isn’t live yet, but will be in the near future. This can be useful if you are trying to coordinate a certificate rotation where it is necessary to change the public key for whatever reason, allowing you to push out an app update first that includes both the existing and new pins.
As discussed, certificate pinning is a useful protection for improving the security of your app’s communications. However, it can be dangerous for the unwary due to the static nature of the pinning in the app. There is a danger of getting yourself into a situation where you need to push out a new version of your app to recover from a certificate pinning issue.
We’ve always recognized this as a limitation of pinning, and Approov includes a dynamic certificate pinning capability. This means that the pins can be updated over-the-air without the risk of downtime due to pin mismatches. You can read about this in Approov Dynamic Certificate Pinning. Moreover, we’ve gone to a significant effort to embed this dynamic pinning in our Frontend Quickstarts, and these support a very wide range of OS versions unlike the platform integrated versions. For ultimate effectiveness and flexibility, please check out these options.