Thursday, November 25, 2010

Keystores and Truststores Using Java API

In general we creates keystores and truststores using keytool of JDK. These keystores and truststores are used to ensure trust between two endpoints (client and server)


Let us see how to create keystores and truststores with keytool.

Create KeyStores and TrustStores

OpenSSL and Java SE 6 keytool creates X509v3 certificates, whereas Java SE 5 or earlier keytool creates X509v1 certificate. If you already have keystores and truststores and you are not sure about version of them, Lets create new keystores and truststores with new X509 private and public key pair.

a) Creating Client Public and Private Key in Client keystore and Server Public and Private key in Server Keystore

keytool -genkey -alias clientX509v1 -keypass keypassword -storetype jks -storepass storepassword -validity 3650 -keyAlg RSA -keystore client-keystore.jks

keytool -genkey -alias serverX509v1 -keypass keypassword -storetype jks -storepass storepassword -validity 3650 -keyAlg RSA -keystore server-keystore.jks

b) Exporting clients public key to an external file and servers public key to an external file

keytool -export -alias clientX509v1 -file client-certfile.csr -keystore client-keystore.jks -storepass storepassword -keyAlg RSA

keytool -export -alias serverX509v1 -file server-certfile.csr -keystore server-keystore.jks -storepass storepassword -keyAlg RSA

c) Import the clients public certificate from the external file to server trust store and servers public certificate to the client trust store


keytool -import -noprompt -alias clientX509v1 -file client-certfile.csr -storepass storepassword -keystore server-truststore.jks -storetype JKS

keytool -import -noprompt -alias serverX509v1 -file server-certfile.csr -storepass storepassword -keystore client-truststore.jks -storetype JKS












Now we have required keystores and truststores with X509V1 certificates. 

Sometimes we may need to access these keystores or truststores from java code to get the public key or private key, to export certificate into a keystore or truststore, to import a certificate from a keystore and etc. Lets see how to do these operations using Java API.


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;


public class KeyStoreOperations {
   
    public static void main(String[] args) {
          // Load the keystore in the user's home directory
          File file = new File("C:/client-keystore.jks");

          KeyStoreOperations  ks = new KeyStoreOperations();

          ks.listAliases(file);
          ks.getCertificate(file);
          ks.addCertToStore(file)
 
    }
   
    private void listAliases(File file) {
        FileInputStream is=null;
        try{
            is = new FileInputStream(file);
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            String password = "storepassword";
            keystore.load(is, password.toCharArray()); // List the aliases
            Enumeration aliasEnum = keystore.aliases();
           
            for (; aliasEnum.hasMoreElements(); ) {
                String alias = (String)aliasEnum.nextElement(); // Does alias refer to a private key?
                System.out.println(alias);
                boolean b = keystore.isKeyEntry(alias); // Does alias refer to a trusted certificate?
                b = keystore.isCertificateEntry(alias);
            }
        }catch(Throwable th){}
               
        finally{
            if(is!=null){
                try{
                    is.close();
                }catch(Throwable th){}
            }
        }
    }
   
    private void getCertificate(File file) {
        FileInputStream is=null;
        try{
            is = new FileInputStream(file);
            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(is, "storepassword".toCharArray()); // Get certificate
            Certificate cert = ks.getCertificate("serverx509v1");
            System.out.println(cert.getPublicKey().toString());
        }catch(Throwable th){}
               
        finally{
            if(is!=null){
                try{
                    is.close();
                }catch(Throwable th){}
            }
        }
    }
   
    private void addCertToStore(File file) {
        FileInputStream is=null;
        FileOutputStream out=null;
        try{
            FileInputStream fr = new FileInputStream("C:/server-certfile.csr");
            CertificateFactory cf = CertificateFactory.getInstance("X509");
            X509Certificate c = (X509Certificate) cf.generateCertificate(fr);
            System.out.println(c.toString());
           
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); // Load the keystore contents
            is = new FileInputStream(file);
            keystore.load(is, "storepassword".toCharArray());
            keystore.setCertificateEntry("aliasname", c); // Save the new keystore contents
            System.out.println("certificate added succesfully");
            out = new FileOutputStream(file);
            keystore.store(out, "storepassword".toCharArray());
        }catch(Throwable th){}
               
        finally{
            if(is!=null){
                try{
                    is.close();
                }catch(Throwable th){}
            }
            if(out!=null){
                try{
                    out.close();
                }catch(Throwable th){}
            }
        }
    }
   
}