Java – SSL communication, how hard can it be

certificate, java, main, private, ssl

I have a Java main application running on my PC that can send XML data to a servelet and recieve XML data back.
http://iamt.wisconsin.gov/IAM-WiEntUser/WiEntUserService?xml=

I can use https://iamt.wisconsin.gov/IAM-WiEntUser/WiEntUserService?xml= from IE and Firefox because I they allowed me to load the private certificate.

I want to use https from the Java main application because some of the data is sensitive. I get an IOException with MSG=unkown certificate. Ok, That makes sense, Java does not know about the private certificate.

I was hoping that it would be as simple as telling Java to trust the FireFox certificates.
System.setProperty("javax.net.ssl.trustStore",
"C:/Documents and Settings/kendajm/Application Data/Mozilla/Firefox/Profiles/6f8ggdi7.default/cert8.db" );
But that gives an IOException with MSG=Invalid keystore format.

SSL communication, how hard can it be? I spent a good eight hours trying to track down how to do this. It seems that is so easy that it is not documented or very difficult and no one has a good example.

Help.

Best Solution

The Mozilla cert8.db key store format is not readable by default (though one could "plug in" a provider that can parse it.) It is easiest to import the certificate into a key store that is supported by default.

First, you need a copy of the certificate.

In Firefox, visit the page in question. Click the "lock" icon on the status bar in the lower right corner of the window. In the resulting dialog, click the "View Certificate" button. A new dialog will appear; select its "Details" tab. Click the "Export" button at the bottom of the window to save the certificate into a file (use DER or PEM format).

Now, you need to get the certificate into a key store format used by Java.

Use the JDK's keytool utility:

keytool -import -keystore mykeystore.jks -alias iamt -file iamt.wisconsin.gov

When prompted for a password, choose a new password that can be used to verify later that the certificates in the keystore have not been tampered with. Next, keytool will prompt you whether to trust the new certificate—enter yes! You should have a new Java key store file named "mykeystore.jks" (or whatever you choose).

Now, run your program, specifying your new key store file as the value of the "javax.net.ssl.trustStore" property.


By the way, I noticed that you are returning Java Beans XMLEncoder output from your service. This "Long Term Persistence" format is an overlooked gem of the JDK, but it is not safe to parse untrusted content. Using this syntax, any method can be invoked in the JVM doing the parsing. It's sort of like "eval" with untrusted JSON. So, if I were implementing a client service, I would not probably not be willing to parse the result from the service without a lot of extra work to "sandbox" the parsing as untrusted code. And I'm assuming the service parses the same format in requests, which is likewise dangerous for the server.


When you ask a question about an error message, it's a great idea to post the entire message, including the stack trace (unless it's actually a java.lang.StackOverflowError!). It might be meaningless to you, but often it has the information one needs to spot the problem in an instant.