March 3, 2017

SSL and Tomcat

A purely technical post this one, because it gave me such a headache this morning trying to figure it out and realising that nowhere was all this written down in one place.

In a Java 6 + Tomcat 6 installation, installing an SSL certificate is usually as easy as uncommenting the appropriate Connector in server.xml to open up port 8443, then importing your SSL certificate using the keytool command. This is well documented across the web so I don't need to go into it here.

However, what is not documented is what happens if your certificate was generated from a private key that was secured using a passphrase, which makes it much more difficult. By default, Java/Tomcat will import it but it cannot use it. You will get errors in the catalina logs complaining about:

java.net.SocketException: SSL handshake errorjavax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled.

In this instance, the solution is to (a) create a version of your private key that has had the passphrase removed, then (b) convert your certificate and private key into a PKCS12 file which contains both of them. You can then (c) merge this PKCS12 file with your Java keystore to enable Tomcat/Java to access the certificate and use it correctly.

Step-by-step:

1. Create a version of your private key file without a passphrase:

openssl rsa -in private.key -out private.key.decrypted

(It will prompt for your passphrase to decrypt the original key.)

2. Create the PKCS12 file:

openssl pkcs12 -export -in mycertificate.crt -inkey private.key.decrypted -out mycertificate.pfx -certfile /path/to/CAcertfile.crt

(mycertificate.crt is the CA-issued SSL certificate. /path/to/CAcertfile.crt is the path to the intermediate certificate for your CA, or the root certificate if no intermediate certificate was issued. You can usually download root certificates from the CA's website. You'll need to specify a password for the PKCS12 file generated.)

3. Merge it with your keystore that you're using for Tomcat (which will be the default Java keystore unless you have configured it otherwise):

keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore /path/to/my/java/keystore -srckeystore mycertificate.pfx -srcstoretype PKCS12 -srcstorepass myPKCS12password -alias 1

(Only works in Java 6 or higher. If you've changed the password on your Java keystore, substitute changeit appropriately. The alias 1 is there to tell it which certificate to import from the PKCS12 file - which, seeing as it only contains one, is index number 1.)

Done!

Topics: Bioinformatics, Blog, java, keytool, openssl, pkcs12, problems, ssl, tomcat