All Ruby on Rails Node JS Android iOS React Native Frontend

3 Ways How To Implement Certificate Pinning on Android

One of the most important things in mobile development is secure communication, especially between the app and its backend server. Currently, the most common architecture of web services is REST based on HTTP. The best protection method for this model of communication is the TLS/SSL standard. It can be combined with HTTP protocol to create its encrypted version called HTTPs. HTTPs ensures safe, encrypted communication channels between client apps and the backend server. Moreover, implementation of this security feature is very simple on Android. You just need to watch out for common pitfalls.

The problem

It’s very common for developers to implement communication over HTTPs, but not in a proper way. This improper implementation is reduced to replacing protocol name in URL from http to https eg. https://www.example.com. Indeed, such implementation will enable TLS/SSL encryption (if the backend server supports it), however, it will not ensure a good enough security level. The TLS standard is based on X509 certificates and asymmetric encryption. So, simply replacing the protocol name will enable encryption, but the app will trust every certificate issued by the server. This means that the attacker can generate their own fake certificate. The certificate will allow to intercept encrypted communication. This kind of attack is called Man-In-The-Middle. It is the main reason to spend more time and effort to implement HTTPs configuration correctly.
mitm_diagram

 

Solution

To avoid this exploit, developers should implement Certificate Pinning. It’s a method that depends on server certificate verification on client side. This verification requires the server certificate or its fingerprint to be previously known to the mobile app. When establishing a connection with the server, the app should compare the fingerprint with a certificate from the remote server. If the fingerprints are identical, then the connection is valid and the data transfer can proceed. If the fingerprints are not equal, then the app should reject the connection immediately, as it’s compromised. The following 3 methods are the most popular ways to implement Certificate Pinning in Android apps.

The old-school way - TrustManager

TrustManager is a component responsible for deciding whether the app should accept credentials submitted by the peer or not. This mechanism is sourced from javax.net.ssl package and you can use it to implement Certificate Pinning in Android apps. Keep reading for a step-by-step tutorial on how to implement pinning using this component.
  1. Add certificate file to the app resources under
    /res/raw
  2. Load KeyStore with Certificate file from resources (as InputStream)
  3. Get TrustManagerFactory and init it with KeyStore
  4. Get instance of SSLContext, bind it with TrustManager and create sslContext with URL connection
As you can see, the solution presented above is quite complex. It also requires handling multiple elements related directly to the framework API. This means that the implementation is placed on a fairly low level. It can lead to some bugs, but keep calm - there is a simpler way to handle the pinning.

OkHttp and CertificatePinner

OkHttp by Square is a very popular HTTP client library for Java and Android. The library is used by one of the most popular tools for handling REST communication in Android - Retrofit. OkHttp provides a mechanism that makes Certificate Pinning implementation easy, as it only requires creating an instance of CertificatePinner using a dedicated builder with corresponding fingerprints. The fingerprints need to be hard-coded in the app, of course. Personally, I prefer to inject such keys during build, using the buildConfigField method. It’s more flexible and safer than keeping the keys in the repository. Then, you need to build the OkHttpClient instance with the CertificatePinner. Here you can see how to do it:

You can add multiple fingerprints for different domains. Multiple fingerprints will also make your app more flexible. You can add all fingerprints from certification path. You can also add additional certificates when the old ones are going to be outdated soon. Fingerprints can be retrieved directly from the certificate. You can also import the certificate file to the resources like in TrustManager case. This time you need to manually write a class that will extract the fingerprint from the file. You can also use Peer certificate extractor to do that for you.

Something fresh - Network Security Configuration

Android platform provides new, easy tool to handle network configuration - the Network Security Configuration (NSC). It has been available since Android 7.0. With NSC you can declare communication methods, including Certificate Pinning, using XML files. To enable the configuration you need to bind a configuration file with the Manifest. To bind it use the networkSecurityConfig attribute in Application tag. Here is a short snippet showing how to handle it:
  1. Create network security config file under
    res/xml/network_security_config.xml
  2. Add the android:networkSecurityConfig attribute to the application tag
  3. Setup configuration file and add fingerprints
As you can see, this method is extremely easy to implement. However, keep in mind it’s only available in API level 24 or higher (for lower levels you can use backported version of the NSC).

Summary

I’ve presented three ways of implementing Certificate Pinning. Personally, I think that the most flexible option is to use CertificatePinner. This method is both short and universal - it works on all Android API levels out of the box. You must use OkHttp as the HTTP client, of course, although the library is very easy to use and pretty much a standard on Android at this point, so it’s recommended anyway.
However, it does not matter which implementation method you’ll use, but always remember that Certificate Pinning is obligatory. It is the only way to provide a truly secure networking, that’s why OWASP Mobile recommends certificate pinning as the protection method for MiTM attack.

 

 

Photo by Rubén Bagüés on Unsplash

We're building our future. Let's do this right - join us
New Call-to-action
READ ALSO FROM Android
Read also
Need a successful project?
Estimate project or contact us