SSL pinning in Android : Using public certificate and BKS file
To prevent MITM(Man in the Middle) attack, we may apply SSL pinning to our apps. There are couple of methods to apply secure socket layer pinning to our apps. It will be more understandable If you want to understand SSL handshake before you deep dive into pinning. Here are some links about SSL and three-way handshaking.
To sum up, in a couple of words, we encrypt our data with our public key, so only our server can decrypt that data with the private key. So If we are using public wifi and send valuable data to our server, the hacker can not sniff our data package because the only way to decrypt is the private key (which is in the server)
As I mentioned earlier, there are couple of methods we can apply SSL pinning. In this topic, I won’t give you all detailed information about all types of pinning. You can find useful and detailed blogpost here.
In this blog post, I will give you the steps how we can implement certificate pinning with BKS file in android apps.
Step 1: Obtain your Public Key certificate
Your certificate can be self-signed or CA-signed certificate. I assume that your certificate is a CA-signed certificate. If you want to check differences between them read this useful post.
To obtain your public key you can ask your security guy in your company or you can easily go to your endpoint (api.sample.com or sample.com, wherever you want to do SSL pinning) from your browser and click on the green lock icon > certificate.
Then drag and drop certificate icon to your desktop. Done. You have a public certificate.
Step 2: Create a BKS file
You need to download bouncy castle jar to create BKS file. The bouncy castle is a crypto API. You can download the latest release from here.
Now you can create your BKS file using keytool and bouncy castle provider.
This command will create a BKS file with your public certificate. If you want to add multiple certificates, run this command with your another public certificate. This command will check the target path and add the new certificate to the existing BKS file so that BKS file will have both certificates inside.
Let’s add multiple certificates to the same BKS file.
As you may see I run same command and keytool will add another certificate into the same BKS file. But be aware of that you should use the different alias name for certificates.
Let’s check if the BKS file really has 2 certificates. To list certificates in your BKS file, you need to run following command.
It will show you the public certificates inside BKS file.
We have successfully created BKS file which contains 2 different public key.
So If you have 2 different endpoint in your app and endpoints doesn’t have same public key, you can use multiple certificate to do ssl pinning in your app.
Step 2: Apply SSL pinning to OkHttp Client
I created a helper class for ssl pinning. This class takes 3 arguments.
- BKS file
- BKS password (which you type in the command line)
You need to locate your BKS file under your res/raw/ folder.
Almost done. All you need is attaching this SSL pinner to your okhttp client.
RawCertificatePinner pinner = new RawCertificatePinner(context, R.raw.mycertificate, "mypassword");OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder = rawCertificatePinner.pinCertificate(builder);return new Retrofit.Builder()
- Collect your public key/keys from your security guy or browser
- Create BKS file using command line (With Bouncy Castle Provider)
- Add BKS file to your res/raw folder
- Create RawCertificatePinner instance
- Attach RawCertificatePinner instance to your okhttp.