Securing the network traffic in Android using Certificate Pinning
In your application, if you are talking to a web Server, how do you make sure that, you are talking the right one ?. Secure channels are the cornerstone to Applications those expect end-to-end security when sending and receiving data — especially sensitive data on channels protected by VPN, SSL, or TLS. Digital certificate or SSL certificate issued by CA(Certificate Authority), act as an identity of a Service hosted in web server. Application can use this certificate to verify identity of the Host he is trying to communicate. This certificate is exchanged during SSL handshake.
What is Certificate public key pinning ?
Associating host name to a public key which will be compared with the public key of the certificate received via SSL handshake. If both the key matches means you are talking to the right server.
Instead of pinning public key from a certificate, complete certificate can be used to verify the identity of the Host.Advantage is that,certificate is easiest to pin. You can fetch the certificate out of band for the website or you can use openssl client to fetch the certificate.
There is a downside to pinning a certificate. If the site rotates its certificate on a regular basis, then your application would need to be updated regularly. For example, Google rotates its certificates, so you will need to update your application about once a month (if it depended on Google services). Even though Google rotates its certificates, the underlying public keys (within the certificate) remain static.
This is also known as SSL pinning. It offers extra protection against man in the middle (MITM) attacks (DigiNotar), perhaps perpetrated using a compromised root certificate.
How to implement pinning in Android using Retrofit
Implement pinning in Retrofit we need two things
- Host to be verified
- public key hash of the host
To implement pinning for api.github.com, we need public key hash from the certificate. I had used openssl to obtain the same.(There are different approach to get this,check the java doc of CertificatePinner)
the above command will give SHA256 hash of the public key. Retrofit exposes a class called CertificatePinner, using this you can bind the public key to the host. Then attach the CertificatePinner to the OkHttpClient. That’s it,we are done !!!.
How to force enable the TLSv.1.2 in Android 16+ devices.
Android TLSV.1.2 is supported from android 16+ and default disabled in below 20+ devices. To gain this support, we have to forcefully enable this by extending SSLSocketFactory.
Add this to sslSocketFactory method of the HttpClientBuilder.
Additionally you can restrict the connection to use only latest TLS version, if the security is the first choice over the compatibility.
you can test the implementation using mitmproxy.
Please find the source code at @github