Tuesday, June 30, 2015

How to import SSL certificate in Java

In this article we see that how to add certificate authority (CA or PFX) certificate to the Java CA certificate (cacerts) store. Here I will show you how to add .pfx certificate that is generated from the IIS server to automatically authenticate while making connection to server. This is normally used for the client authentication and termed as the two way SSL Authentication 

You cannot directly use .pfx file and import it to java keystore, you need to convert it into PKCS12 (.p12) and load dynamically using java code. Java keytool is capable of doing this using some keytool import command show in below although it is only available from JDK 1.6 or later

You can learn more about keytool documentation at Java Doc here.

To add a certificate to the cacerts KeyStore or Java Keystore


  1. Go to the directory where your .pfx file is present. I hope that you have set JAVA_HOME environment variable so that you can directly execute keytool command ( to check it execute “java –version “ command from command prompt)
  2. Convert .pfx file to .jks file using “keytool –import “ command. Go to folder where your file is located and execute following command :
          keytool -importkeystore -srckeystore mykey.pfx -srcstoretype pkcs12 -destkeystore clientcert.jks -deststoretype JKS
           
          Attribute Details:- 
          -importkeystore – Imports a single entry or all entries from a source keystore to a destination keystore.
          -srckeystore – Source file path 
        -srcstoretype – Source file key store type  
  -destkeystore – Destination file path
          -deststoretype – Destination file key store type

     3. Now next step is to convert your .jks file to .p12 file which is used by java to add it to keystore.
        To do this below is command to execute

            keytool -importkeystore -srckeystore clientcert.jks -destkeystore KEYSTORE.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass srcstorekeypassowrd -deststorepass deststorekeypassowrd -srcalias srcaliasname -destalias myalias -srckeypass srcstorekeypassowrd -destkeypass deststorekeypassowrd –noprompt

           In above command you need to pass source key password which you will get from the key provider or where your .pfx file is generated. 
           
           Source alias is alias name present in the key file you can find it by below command

           keytool -list -storetype pkcs12 -keystore mykey.pfx -v | grep Alias
        4. Now your .p12 file is ready to include it in Java Keystore by below command

            keytool -importcert -trustcacerts -alias myalias -file KEYSTORE.p12 -keystore /usr/local/java7.45/jre/lib/security/cacerts -storepass changeit
            
             java keystore path is path where your java is install. “cacerts” is file present in java where all your certificate are store, and to add new certificate it has default password “changeit”

Include certificate in Java code

           Now you need to include this certificate .p12 to every request made from java code to remote server. Sample program for this is given below.

       public void callWebservice(String webserviceUrl, String requestData)
       {     
          HttpsURLConnection con = null;   
          String certificateFilePath,certificatePassword;
          Gson gson = new Gson();
          OutputStreamWriter dos = null;
          InputStreamReader dis = null;
          try
          {            
             certificateFilePath = "WEBSERVICE_CERTIFICATE_FILE_PATH"//Certificate file path
             certificatePassword = "WEBSERVICE_CERTIFICATE_PASSWORD";   //Certificate keystore password
                   
             //Load your certificate in keystore
             char[] passw = certificatePassword.toCharArray();
             KeyStore ks = KeyStore.getInstance("PKCS12");
             InputStream keyInput = new FileInputStream( certificateFilePath);

             ks.load(keyInput, passw );
             keyInput.close();

             //Add your certificate in trustmanager factory
             KeyManagerFactory kmf =                                                                  KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
             kmf.init(ks, passw);

             //Include your certificate in SSL request
             SSLContext sclx = SSLContext.getInstance("SSL");
             sclx.init( kmf.getKeyManagers(), null, new SecureRandom());
             SSLContext.setDefault(sclx);
                                                                                                        HttpsURLConnection.setDefaultSSLSocketFactory(sclx.getSocketFactory());

             URL url = new URL(webserviceUrl);
             con = (HttpsURLConnection)url.openConnection();

             if(con!=null)
             {
                con.setRequestProperty("Content-Type","application/json;charset=utf-8");
                con.setRequestProperty("Accept", "application/json");
                con.setRequestProperty("Accept-Charset", "UTF-8");
                con.setDoOutput(true);
                con.setDoInput(true);
                con.setUseCaches(false);
                con.setDefaultUseCaches(false);
                con.setRequestMethod("POST");
                con.connect();
             
                dos = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
                dos.write(requestData);
                dos.flush();

                dis = new InputStreamReader(con.getInputStream(),"UTF-8");

                 if (null != dis)
                 {                         
                    BufferedReader reader = new BufferedReader(dis);
                    String line,strbuf = null;
                    if((line = reader.readLine()) != null) {
                        strbuf = line;
                    }
                    System.out.println(strbuf);
                    reader.close();                         
                  }
                }
           }
           catch(IOException ioex)
           {            
               System.out.println("IO Exception "+ioex.getMessage());
               ioex.printStackTrace();
           }
           catch(Exception ex){
               System.out.println(" Exception "+ex.getMessage());
               ex.printStackTrace();            
           }
           finally{
              try{
                   if(dos != null) {
                        dos.close();
                   }
                   if(dis != null) {
                       dis.close();
                   }
                 }
              catch(Exception ex)
              {
                 System.out.println("Exception in close IO stream"+ex.getMessage());
                 ex.printStackTrace();     
              }
          }
    }
Above example will send your request with certificate include using SSL configuration.


Please let me know if you have any query regarding this. You may write your question in comment section i will tried to give answer as soon as possible.