Monday, May 12, 2008

Java and self-signed SSL certificates

It is very common in test environments to employ self-signed SSL certificates in HTTP servers (e.g., Apache HTTPD, Tomcat) rather than certificates issued by trusted commercial Certification Authorities. When trying to open a SSL connection to a host using a self-signed SSL certificate, however, the JSSE throws the following exception:
javax.net.ssl.SSLHandshakeException: (...)
unable to find valid certification path to requested target

Andreas Sterbenz provides a very nice guide that shows you how to add a self-signed SSL certificate to the keystore with your app's trusted certificates. It basically comes down to 4 steps:
  1. Use his InstallCert java program to make a request to the host with the SSL certificate you want to trust. Assuming the host address "somehost.com" and the port for the SSL connection is "8443", you should compile the InstallCert.java file and execute it with these parameters:
    java InstallCert somehost.com:8443
  2. Following the instructions on the guide, after the exception you should receive a list of SSL certificates from the host. If you decide to trust one of them, pick the number corresponding to that certificate.
  3. If you picked one of the available certificates, the InstallCert program will generate a file called jssecacerts on the directory where you executed the program.
  4. To use the newly added certificate when establishing SSL connections to "somehost.com", add the following line your java application:
    System.setProperty("javax.net.ssl.trustStore", "path/to/jssecacerts");

    where "path/to/" represents the full path to your jssecacerts file
And that's it! Now you can try creating an HttpClient and performing an HTTP/GET operation to see it working :-)