Managing Trust Stores Across Java Versions
My debugging contest of the week happened to take place on a IBM AIX system. The bug happened when we upgraded from Java version 1.4 to version 6 (which I admit is a pretty big step). Suddenly, an old application stopped working and its log displayed NoSuchAlgorithmException.
A bit of context: when Java applications have to connect to hosts with SSL over HTTP, they must trust the host – it’s the same as when you browse a site with HTTPS. If the site can provide a SSL certificate that can proves its trustworthiness by tracing it back to a trust authority (Verisign and others), all is well. However, when browsing, you can always force the browser to trust a certificate that is not backed by a trusted authority. Such a luxury is not permitted when running an application, there’s no callback.
Therefore, you can add certificates to the JVM truststore, which is located under the $JRE_HOME/security/lib. Alternatively, you can also pass a truststore with the -Djavax.net.ssl.trustStore=<path/to/store> Java launch parameter. Before this problem, I was foolish to think you could keep the same truststore between different Java versions without a glitch. This is not the case: going back and forth a few times, we finally located the root problem.
It seems that between Java version 1.4 and 6, the good people at IBM decided to completely change their security providers. This means that when a certificate is stored by a Java 1.4 JVM, the Java 6 JVM has no chance to read it.If you’ve had told me that before then, I would have laughed in your face. Reality is weirder than fiction.
Conclusion: for Ops, it may be a good idea to consider always using the same security provider regardless of the operating system. Bouncy Castle is one of such providers, others surely exist.
Note: Sun may be defunct, but their engineers kept the same security providers between Java 1.4 and 6