Ok, one more post aimed at my memory, but that can end up helping others as well 😉
I’ve been playing around with digital certificates in Java, because I’ll have to implement some stuff here that requires secure calls to web services using them.
One of the requirements for the secure connection is that our server trusts the Web Service’s server. To do this we have to, somehow, install a certificate chain provided by the Web Service provider. Sounds pretty simple, but can be a little bit troublesome if you are not familiar with how Java works with digital certificates and also with how to handle the keystore tool that comes with the JVM.
At first, I tried to import the certificate chain using the keystore directly, without success. The chain provided is a .pb7 file, which I discovered later that follows the PKCS #7 format / standard / whatever. Having never dealt with such a file before, I had no idea of what to do with it. I just knew I had to import it in my local (or server, when in production) trusted certificate store. But I couldn’t find the proper parameters to pass to keystore so that it would do the right thing…
I gave up this approach for a while and started to google around for some solution. This is when I found the KeyStore Explorer application. It is a free tool that really helps visualizing digital certificates, both installed and the ones available in specific certificate files. I installed the tool, and with some guessing I found how to visualize the .pb7 file mentioned before. Strangely, I had to do some manual labour to import the chain of certificates: I visualized, one by one, all of the certificates in the chain, and exported each one to .cer files. After that, I opened the trusted store and imported all of those certificates into it. Done.
Of course, this solution is not ideal, but works. The ideal would be to import the chain directly using the keystore tool, which is probably possible, I just could find exactly how. If you do know how to do this, please leave a comment =)
Heya.
In order to implement secure calls to webservices, all you need to do is build a keystore containing the endpoint certificate and those of your own to close up the handshake process.
To do this, you may use the keytool.exe tool provided with the Sun JDK, or use a nifty little tool such as the one you discovered – or KeyTool GUI (check out http://www.jars.com/utilities/resource.php/26751).
If you’d rather use the sun tool, check out http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html for more info.
As far as code is concerned, you need to load your keystore into the session:
System.setProperty(“javax.net.ssl.trustStore”, “/path/client.keystore”);
System.setProperty(“javax.net.ssl.keyStore”, “/path/client.keystore”);
System.setProperty(“javax.net.ssl.trustStorePassword”, “somePassword”);
System.setProperty(“javax.net.ssl.keyStorePassword”, “somePassword”);
if you want to add debug info,
System.setProperty(“javax.net.debug”, “ssl”);
An important point is to remember that you need the server’s certificate file to be in your keystore, or the connection will most likely be refused.
Thank you for the information!
What I did was to add the server’s certificate to the cacerts files. Now, this is probably overkill… If I setup a new keystore as you describe, then I won’t need to touch cacerts?
Also, can I use this new keystore to hold both the local and the remote certificates?
Actually, I’ll have to choose the proper local certificate based on which user is currently logged into the system, but this shouldn’t be a problem as long as I’m not dealing with the (sort of) protected cacerts file.
Anyway, thank you again, I’ll play certainly use this information =)
Heya.
Actually in my application I used a single keystore to hold both files, and just repeated the reference in both trust and keystore settings in the code.
hope it helps 🙂
Ah, sorry, forgot abotu something. In order to import the chain directly with keytool, use the following prototype:
keytool -import -alias someAlias -file someFile.PEM -trustcacerts -keystore cacerts -storepass somePass.
.p7b format usually messes things up and may not be recognized as a x509 repository depending on your OS.
To make the cacerts file, you just need to copy/paste the base64 encoded certs one after another using any simple text editor like notepad or cat.
Also, there’s no way to import a certificate chain unless it’s associated to a private key.
About importing the chain, maybe that’s why I had to extract all the certificates in the chain and add them one by one to my cacerts.
About the .pb7 file, I’m stuck with it because its the only format provided by the Web Service provider. Well, at least extracting all certs from it works, so no big complains here =p