opencodez

Read X509 Certificate from Java KeyStore – Example With Code

In the NEW IT age with lots of data comes great responsibility to protect it against all malicious attacks. Using secure communications or HTTPS is one of the ways to protect the data while it travels the web. Now when we talk about https, we use different certificates.

In this article, we will see how we can generate a self-signed X509 certificate. We will generate it using Java Keytool and then we will write a utility to read the private key and X509 certificate from Keystore.

X509 Certificate:

X509 defines the format of public-key certificates. The certificates are used in many internet protocols like TLS, SSL. Apart from this, the certificates are used to implement PKI authentication for many offline applications as well as web applications. An X509 certificate contains a public key and an identity (a hostname, or an organization, or an individual).

A certificate authority can sign your certificate or you can self sign it. The users can then use this certificate to establish secure communication with different parties. The user can also use to validate the digitally signed documents or communications using the private key he has.

First, we will see how we can use Java Keytool to generate a key store that will have our self signed X509 certificate and its corresponding private key.

keytool -genkey -alias opencodez -keyalg RSA -validity 1825 
-keystore "opencodez.jks" 
-storetype JKS -dname "CN=www.opencodez.com,OU=Opencodez,O=Opencodez,L=Pune,ST=Maharashtra,C=IN" 
-ext san=dns:opencodez.com,dns:OPENCODEZ.COM -keypass op3n.cod3z 
-storepass op3n.cod3z

Here I am assuming that you have the latest Java installed on your machine and the keytool utility is available on your command prompt.

In the above command, I have given all the options in one go so that you donxt have to respond to the prompts the keytool gives you. The command will create a JKS file named xopencodez.jksx and it will have a X509 certificate for CN or Common Name xwww.opencodez.comx. You can find more details about the various keytool options on its official link. You can list and check your JKS as below

If you need, you can export the certificate using the below command and check. You need to provide the password when prompted.

keytool -exportcert -alias opencodez -keystore opencodez.jks -file opencodez.cer

Once exported you can double click the certificate file xopencodez.cerx and you will see the details like below

As the certificate is self-signed you will see the issued to and issued by the same.

Read X509 Certificate in Java

Now we will see how we can read this from our Java Program. As we have seen the java key store has two parts, one is the private key and the other is a public x509 certificate associated with the key. We will have a small class, that will hold these 2 together for better handling. The Java Security has pre-defined classes for key and certificate.

package com.opencodez.util;

import java.security.PrivateKey;
import java.security.cert.X509Certificate;

public class CertificateDetails {
	
	private PrivateKey privateKey;
	
	private X509Certificate x509Certificate;


	public PrivateKey getPrivateKey() {
		return privateKey;
	}

	public void setPrivateKey(PrivateKey privateKey) {
		this.privateKey = privateKey;
	}

	public X509Certificate getX509Certificate() {
		return x509Certificate;
	}

	public void setX509Certificate(X509Certificate x509Certificate) {
		this.x509Certificate = x509Certificate;
	} 
}

After this, we will write a simple utility, that will give is an object of the above class with key and certificate filled in. The Java KeyStore class can load your JKS file, when its supplied with the JKS file path and password as a character array.

The program loads the Keystore file and iterates through all the aliases we have added in our JKS file. The program checks if any alias is associated with a key, if it is, then it will break and read the corresponding key and certificate.

package com.opencodez.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableEntryException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;


public class CertificateUtil {

	public static CertificateDetails getCertificateDetails(String jksPath, String jksPassword) {

		CertificateDetails certDetails = null;

		try {

			boolean isAliasWithPrivateKey = false;
			KeyStore keyStore = KeyStore.getInstance("JKS");

			// Provide location of Java Keystore and password for access
			keyStore.load(new FileInputStream(jksPath), jksPassword.toCharArray());

			// iterate over all aliases
			EnumerationxStringx es = keyStore.aliases();
			String alias = "";
			while (es.hasMoreElements()) {
				alias = (String) es.nextElement();
				// if alias refers to a private key break at that point
				// as we want to use that certificate
				if (isAliasWithPrivateKey = keyStore.isKeyEntry(alias)) {
					break;
				}
			}

			if (isAliasWithPrivateKey) {

				KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,
						new KeyStore.PasswordProtection(jksPassword.toCharArray()));

				PrivateKey myPrivateKey = pkEntry.getPrivateKey();

				// Load certificate chain
				Certificate[] chain = keyStore.getCertificateChain(alias);

				certDetails = new CertificateDetails();
				certDetails.setPrivateKey(myPrivateKey);
				certDetails.setX509Certificate((X509Certificate) chain[0]);

			}

		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (UnrecoverableEntryException e) {
			e.printStackTrace();
		}

		return certDetails;
	}

}

The usage is simple as shown here

CertificateDetails certDetails = CertificateUtil.getCertificateDetails("C:\\opencodez.jks", "op3n.cod3z");
System.out.println(certDetails.getPrivateKey());
System.out.println(certDetails.getX509Certificate());

Once you run this, you can see the string representation of key and x509 certificate on console as below. Please note that, I have not captured complete console output.

Conclusion

I hope, the readers have gained some insights about X509 certificates. More importantly, you have learned how you can read the certificate in java. Now you can use it in any of your security projects and provide more secure projects, applications.

Happy Sharing!!!