Friday, March 15, 2013

Use HTTPS connection in android app

Note : For this tutorial I am using Ubuntu platform 


1) If you are working on android application with client - server model. And services expose by servers are on SSL connection (i.e https://myserver/login?email=&password) then you need settings in your android applications.


1) Download the certificate. for demonstration I am using a link (i.e https://www.google.com) and chrome browser.
  a) Open chrome and this link : https://www.google.com
  b) Press Lock icon on you url bar and then select Connection tab
  c) Then select Certificate information
  d) You will see a pop up. Select details tab and Select top of Hierarchy under  Certificate Hierarchy section.
   e) press export button and save certificate in you directory.


f)  Certificate will be like :
-----BEGIN CERTIFICATE-----
MIIDIDCCAomg..........................................
-----END CERTIFICATE-----

2) Download  BouncyCastle Provider and put it will you SSL certificate file.
3) Open terminal and open your Oracle JDK bin folder
    cd /usr/lib/jvm/java-7-oracle/bin

4) use blow command to create a keystore file mykeystore.bks with

 password mysecret

keytool -importcert -v -trustcacerts -file "/path/Builtin Object Token:Equifax Secure CA" -alias IntermediateCA -keystore "/path/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "/path/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret
5) To verify mykeystore.bks use below command on same terminal
keytool -list -keystore "/path/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "/path/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

you will get result like
Keystore type: BKS
Keystore provider: BC

Your keystore contains 1 entry

IntermediateCA, Mar 14, 2013, trustedCertEntry,
Certificate fingerprint (SHA1): D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A
 6) Now put mykeystore.bks in to your android project/res/raw/mykeystore.bks


7) Now use  mykeystore.bks into get response input stream from your request.
    you can get code here 

private static InputStream getHttpInputStream(String urlAddress,Context ctx)  throws KeyManagementException, NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, UnrecoverableKeyException{
        TrustManagerFactory tmf;
       
        KeyStore trustedStore = loadClientKeyStore(ctx);
        tmf = TrustManagerFactory.getInstance("X509");
        tmf.init(trustedStore);

        SSLContext ssl_context = SSLContext.getInstance("TLS");
        ssl_context.init(null, tmf.getTrustManagers(), null);
       
       
        HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
       
        URL u = new URL(urlAddress);
        HttpsURLConnection urlConnection = (HttpsURLConnection) u.openConnection();
        urlConnection.setSSLSocketFactory(ssl_context.getSocketFactory());
        urlConnection.setHostnameVerifier(hostnameVerifier);
        urlConnection.connect();
       
        return (InputStream)urlConnection.getInputStream(); 
    }

    private static KeyStore loadClientKeyStore(Context context) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
            InputStream in =  context.getResources().openRawResource(R.raw.mykeystore);
            KeyStore trusted = null;
            trusted = KeyStore.getInstance("BKS");
            trusted.load(in, "mysecret".toCharArray());
            in.close();
            return trusted;
    }