Thursday 7 February 2013

Java and trusting self-signed SSL certificates

Self-signed SSL certificates crop up regularly in internal environments, and can result in your Java application complaining.

For example, say a Maven build attempts to download jar files from a server with a self-signed certificate.  You may get an error similar to:
peer not authenticated
The problem is you need to let the application know it can trust this server.

The JSSE Reference Guide states the following steps will be tried to find trust material:
  1. A file defined by the javax.net.ssl.trustStore system property
  2. The <java-home>/jre/lib/security/jssecacerts file
  3. The <java-home>/jre/lib/security/cacerts file
Note if the file is found in any step, that file is used and no more steps are applied.  Note further that if the trustStore property is set, but the file does not exist an empty file will be assumed.

I generally add the self-signed certificate to the jssecacerts file (default password is "changeit").  If this file does not exist you can create it with a copy of cacerts, or simply run the command below and it will create the file (and you will be prompted to enter a new password). 

A simple way to get hold of the certificate is to navigate to the site in your browser and then store the certificate in x509 format (in Firefox: click on padlock next to the URL and press "More Information", "View Certificate", "Details" tab, "Export".  Save as x509(PEM))

To add this certificate to your truststore, type the following command:
keytool -importcert -file <file> -alias <alias> -keystore %JAVA_HOME%/lib/security/jssecacerts 
And finally a quick sanity check of the truststore:
keytool -list -alias <alias> -keystore %JAVA_HOME%/lib/security/jssecacerts