SSL Pinning — Make your application secure

SAURABH OMER
Bobble Engineering
Published in
4 min readDec 18, 2020

Nowadays We are using HTTPS in a network layer and network layer is enough to be sure that user data transfer will be fully secured. In most cases that is true, but not always. Sometimes sensitive data has to be shared between applications and servers and for this data.

What is SSL?

SSL stands for Secure Sockets Layer. It is provide more security between server and client and establish an encrypted link between a server and a client. This link ensures that all data passed between the web server and browser remain private.

What is SSL Pinning :

SSL Pinning is ensuring that any client SSL request first validates that the server’s certificate exactly matches the bundle’s certificate previously stored in the application.

Why using SSL Pinning?

most of the popular apps and websites nowadays implement SSL pinning as one more layer of defense against a Man-in-the-Middle (MitM) attack.A man-in-the-middle (MitM) attack is when an attacker intercepts communications between server and client either to secretly eavesdrop or modify traffic traveling between the two.

How do we implement certificate pinning?

Relying on matching certificates between device and server opens up a security hole since anyone can generate their own certificate and private key, so a simple handshake between these two actors doesn’t prove anything but the server knows the private key that matches the public key of the certificate. Certificate pinning does by ensuring a specific server public key is used to initiate secured traffic.this idea is to prevent a man in the middle attack.

To implement in android, get a certificate and get one or more public keys for the desired host.So client machine sends a connection request to server, server listens the request.Server gives response including public key and certificate.Client checks the certificate and sends an encrypted key to server.Server decrypt the key and sends encrypted data back to the client machine as server response.Client receives encrypted data and decrypts data using public key. So encrypted data is decrypted in right public key. so this logic is to prevent a man in the middle attack.

You can retrieve the certificate’s public key and include it in your code as a string. At runtime, the app compares the certificate’s public key to the one hard-coded hash string in your code.

String hostname = "https://myexample.com/";
CertificatePinner certPinner = new CertificatePinner.Builder()
.add(hostname,
"SHAKey");
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.certificatePinner(certPinner)
.followRedirects(false)
.followSslRedirects(false)
.build();

AndroidNetworking.initialize(getApplicationContext(),okHttpClient);

if you have more than one certificate’s public key and hosts:

String hostname1 = "https://myexample1.com/";
String hostname2 = "https://myexample2.com/";
//SHA keys for hostname1 url.
String[] SHAKeyList1 =new String[3] ;
SHAKeyList1[0] ="sha1";
SHAKeyList1[1] ="sha2";
SHAKeyList1[2] ="sha3";
//SHA keys for hostname2 url
String[] SHAKeyList2 =new String[3] ;
SHAKeyList2[0] ="sha1";
SHAKeyList2[1] ="sha2";
SHAKeyList2[2] ="sha3";
//SHA keys for hostname1 and hostname2 url
String[] SHAKeyList3 =new String[3] ;
SHAKeyList3[0] ="sha1";
SHAKeyList3[1] ="sha2";
SHAKeyList3[2] ="sha3";

CertificatePinner certPinner = new CertificatePinner.Builder()
.add(hostname1,
SHAKeyList1)
.add(hostname2,
SHAKeyList2);
.add(hostname1,
SHAKeyList3);
.add(hostname2,
SHAKeyList3);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.certificatePinner(certPinner)
.followRedirects(false)
.followSslRedirects(false)
.build();

AndroidNetworking.initialize(getApplicationContext(),okHttpClient);

API calls :

Rx2AndroidNetworking
.get(ApiEndPoint.CONTENT_MOVIE_GIF_DEFAULT)
.addQueryParameter ("apiKey",apiKey)
.addQueryParameter ("randomId", "ABCD")

.addQueryParameter("timezone",getTimeZone())
.addQueryParameter("locale", "")
.build()
.getObjectSingle(Model.class);

Create network_security_config.xml file ,add certificate’s public key in <pin-set> tag and add host in <domain> tag like this:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">api.abd.com</domain>


<domain includeSubdomains="true">a.abc.net</domain>
<pin-set>
<pin digest="SHA-256">AAA4</pin>
<pin digest="SHA-256">AAA3</pin>
<pin digest="SHA-256">AAA2</pin>
<pin digest="SHA-256">AAA1</pin>
<pin digest="SHA-256">AAA</pin>
</pin-set>

</domain-config>
</network-security-config>

Add network_security_config.xml in manifest file :

<application
....
android:networkSecurityConfig="@xml/network_security_config"
.....
>

if the certificate’s public key is right, API gets success otherwise API gets an error message like this.

Conclusion :

More and more users and businesses use smartphones to communicate with server, he has all type of sensitive information.SSL pinning helps build secure mobile applications but it will not secure connections if the pinned host is compromised. It mainly protects the client however it also helps protect the servers by making it harder for hackers to snoop on the traffic and figure out your API and exploit other security holes.

Sharing one useful link below —

Cheers.

--

--

SAURABH OMER
Bobble Engineering

Passionate Android Developer from NIT Durgapur, dedicated to crafting innovative and user-centric mobile experiences.