Friday, December 27, 2013

Custom SSLSocketFactory that trusts only your Certificate.

pre { color: #ffffff; background: #6A6A6A; }
Whenever you connect to a secure website that doesn't use a CA(Certificate authority) that is a trusted 3rd party your are most likely to get

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

when connecting through a java program or an android app.

To fix this you'll have to tell your network client to trust that sites certificate. You'll find that when using Apache Http client you have to create your own custom SSLSocketFactory or set a custom sslsocket to the connection as described at developer.android.com when using HttpUrlConnection.

To save yourself all that trouble you can use my already created custom SSLSocketFactory which works with both Apache Http Client and HttpUrlconnection.

https://gist.github.com/Shalzz/8125772

To actually use it you'll need to write a few lines of code.

For HttpURLConnection


MySSLSocketFactory sslf = null;
        try {
         KeyStore ks = MySSLSocketFactory.getKeystoreOfCA(this.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 the DefaultHttpClient created with KeyStore containing our Certificates.