The one thing that will put any systems admin in an early grave.

This is one of those things that any sysadmin especially one that doesn’t work in a Java shop or deal with it on a daily basis will come to loathe and in turn have a dire hatred for Java. The biggest bane is Self Signed certificates often used in development.

Hopefully some collective knowledge will help those that have to deal with this.

The Stores

There are two components to Java SSL

  • keystore A Java KeyStore (JKS) is a repository of security certificates – either authorization certificates or public key certificates – plus corresponding private keys, used for instance in SSL encryption.
  • cacerts The Java cacerts is a certificate trust store used for authenticating peers.

The fundamental difference to remember is that the cacerts houses the ROOT CA certificates and by default is compiled with well known and trusted issuers. While the keystore is for your own certificates.

The keystore

The keystore is the most difficult to manage because you cannot use your standard RSA keys. They must be in a PFX / pkcs12 format.

Generate a Keystore

Create the Key.

  • openssl genrsa -aes256 -out server.key 4096

Create the CSR

  • openssl req -new -key server.key -out server.csr

Create the self signed Cert

  • openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Combine the Key and Cert

  • cat server.key server.crt > example.pem

Convert the Key and Cert into a PFX/pkcs12 formatted one (Note use the same password as used for the key)

  • openssl pkcs12 -export -in example.pem -out example.pkcs12 -name "example

Verify the Keystore

  • keytool -v -list -storetype pkcs12 -keystore example.pkcs12

You can also import the pkcs12 formatted certificate into an existing keystore.

This is used to serve SSL requests via Tomcat, JBoss, or any Java Process that needs to use SSL.

The cacerts

Because Java has a standard set of trusts it will not allow communication to anything over SSL if it cannot find a trusted cert.

In the case of Self Signed certificates, if your Java process needs to communicate with another service that is running behind a Self Signed Certificate you need to import the cert into the Java cacerts located at $JRE_HOME/lib/security/cacerts.

You will first need to obtain the cert. Usually you can just export this out of a browser window or obtain it from your friendly neighborhood sysadmin.

Then simply import it into the cacerts with the Java keytool with a default password of changeme.

Importing the Cert

First list the cacerts to make sure it doesn’t already exist.

  • keytool -list -keystore cacerts | grep $CERT_ALIAS

If it doesn’t exist import it.

  • keytool -keystore cacerts -importcert -alias example_crt -file server.crt

Check to validate it imported successfully.

  • keytool -list -keystore cacerts | grep $CERT_ALIAS

Now your Java process should be able to successfully talk to the service running behind the self signed certificate.

The Wrap Up!

This was spawned from myself spending countless hours debugging network and connectivity issues between Java processes and third party integrations where the culprit turned out to be a self signed certificate. I have often stated that Java SSL will put any sysadmin into an early grave. So hopefully this will help some fellow engineers out there and spare them the pains that others of us have suffered. This method is also applicable to .net applications. Even though the exact commands are not the same, .net applications have their own cert and key stores that need to be updated to properly work with Self Signed Certificates.