Shaleen Jain

ยท 1 min read

Trusting a Self-signed SSL Certificate

When connecting to a server which has setup their SSL encryption with a self-signed certificate through a Java or an android app, you'll get an SSLException since their certificate isn't signed by a Certificate Authorities (CA) which is a 3rd party who is trusted by everyone.

javax.net.ssl.SSLException: Not trusted server certificate exception

If you have access to the server or know the site admin, get them to buy a CA signed SSL certificate.

But in case that is not possible or feasible we can one thing we can do is configure our HTTP client library to just not verify the site hostname with the certificate. But then again that is not a good solution and defeats the whole purpose of encryption.

A more elegant solution is to tell the client library to explicitly trust a certificate. We'll have to manually get a copy of the site's self-signed certificate that we can use to tell our client to trust.

Java has a couple of HTTP clients, mainly:

You'll find that when using Apache Http client we'll have to create a custom SSLSocketFactory to implement the above functionality. And for HttpUrlConnection set a custom SSLSocket to the connection as described at developer.android.com.

Here is a reference implementation that does just that.

๐Ÿ”—For HttpURLConnection

MySSLSocketFactory sslf = null;
try {
    KeyStore ks = MySSLSocketFactory.getKeystoreOfCA(getResources().openRawResource(R.raw.myCert));
    sslf = new MySSLSocketFactory(ks);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    sslf.fixHttpsURLConnection();
}

Here we create a Keystore containing our certificate, in this case myCert. Which we then use to get an instance of MySSLSocketFactory and then call its non static fixHttpsURLConnection() method. This sets the SSLSocketFactory created as the default SSLSocketFactory for HttpURLConnection.

๐Ÿ”—For Apache Http Client

MySSLSocketFactory sslf = null;
DefaultHttpClient client  = null ;
try {
    KeyStore ks = MySSLSocketFactory.getKeystoreOfCA(this.getResources().openRawResource(R.raw.myCert));
    client  = MySSLSocketFactory.getNewHttpClient(ks);
} catch (Exception e) {
    e.printStackTrace();
}

In this case we get a DefaultHttpClient created with the KeyStore containing our Certificates.

Originally posted at coding-euphoria.blogspot.in
Edited and updated on 20/07/2017

Liked this article? Buy me a beer on the Bitcoin Lightning Network

Got any questions or comments? Drop me a message on Twitter @shalzzj or comment below.