Tuesday, May 29, 2012

How to register SSL certificates in your JVM?

You wrote a Java program which needs to access to a external ressource through SSL (such as LDAPS or HTTPS)?

Okay, this post is for you.

The first thing you have to know is that the first time you established a secured connection to something, you (normally) have to accept the certificate used to encrypt the dialog. In apps with interaction with end users (such as a web browser), the user often see a popup which asks him to trust the certificate. But, if the secured connection is establised behind the scene  (without any possibility to show a popup to somebody, such in batch process apps), the certificate must be trusted before establishing the connection.

In Java, there's a wallet which contains trusted certificate. It is located in [JAVA_HOME]/jre/lib/security/cacerts

I explain here how to extract the public key of a SSL certificate and how to register is in the cacerts file.

Step 1 : let's extract the public key from a secured connection

We will use OpenSSL for that. Just run from a shell :
openssl s_client -connect [URL_TO_REACH]:443 > cert.pem

This will generate a file "cert.pem". Edit this file and remove the text before and after the certificate (You will understand while you will see it)

Step 2 : register the cert.pem in the cacerts wallet

There are four prerequisites to know :
  • the certificate has to be associated with a n alias in the wallet (and you will see that you will be able to remove it from the wallet by this alias later)
  • for unix users, you have to be root to register a certificate
  • the default password of the cacerts wallet is "changeit"
  • don't forget to restart your program after having registered the certificate
 To register your cert.pem, just do :
su -c "[JAVA_HOME]/jre/bin/keytool -import -alias [MY_CERT_ALIAS] -keypass changeit -keystore [JAVA_HOME]/jre/lib/security/cacerts -file cert.pem"
(Don't forget to replace [JAVA_HOME] and [MY_CERT_ALIAS] with your own values.

If you need to remove this certificate, just do :
su -c "[JAVA_HOME]/jre/bin/keytool -delete -alias [MY_CERT_ALIAS] -keypass changeit -keystore [JAVA_HOME]/jre/lib/security/cacerts"

That's all.

UPDATE (October 2016) : 

If you have an handshake failure, try this :

openssl s_client -tls1 -connect [URL_TO_REACH]:443 > cert.pem