New Location

My website has moved to Please visit there for the latest and only remain here for legacy content.

Thursday, September 3, 2009

Certify This - Export IIS Certificate and Private Key and Import to Java Keystore

Here's the scenario. Our shop has a certain application out in the wild that expects to be able to hit some pre-existing https:// url's hosted presently on a windows machine running a .NET web application. Accessing those url's with http over ssl is mandatory, as the application will not attempt to fall back to http on port 80. We are also in the middle of porting those .NET web applications to a Java based web infrastructure. In order to serve those same urls with https from java from our application server, a Java keystore must be used to handle SSL/TLS requests from http clients.

I end up asking both a lead developer and a system administrator for the certificates used. The lead developer obliges with .pfx file, which is a pkcs12 file. The system admin pops over a .cer file in the form of a pkcs7 file.

To make a long story short, the pkcs12 is the one that you will want. You can retrieve a pkcs12 (extension of .pfx in Windows land) by following the documentation here at MSDN - there is a section devoted to exporting.

Using openssl, you can view the full contents of the pkcs12 file with the following:
`openssl pkcs12 -in thefile.pfx`  #The full contents
`openssl pkcs12 -in thefile.pfx -nokeys` #Show only the certificates in the chain
`openssl pkcs12 -in thefile.pfx -nocerts` #Show only the private key.
In order to actually use these commands, you'll be challenged for an "Import Passphrase" that was set on whatever tool generated this file. In in our case, this is IIS).

This is fine and all, but this file can't really be placed in to a pre-existing java keystore, or a new one for that matter, by using the keytool utility - the common and suggested way to manipulate java keystores. The keytool utility basically assumes it is going to either 1) have certificates placed in it to know what to trust as an ssl client or 2) be created with a public/private key pair that will be used to generate a csr and accept certificates from that csr that match the key pair. It does not allow you, intrinsically, to import a pre-existing private key or keypair that match already pre-existing certificates so that your application or application server can act as a server for ssl/tls communication with those pre-existing certificates.

The solution - there's a little library called Not Yet Common SSL that let's you do just that. It was being actively developed on until June of this year. I grabbed the 0.3.9 version (0.3.10 didn't work for me... I'll spare the details) and issued the following commands using the pkcs12 file as input.
`java -cp not-yet-commons-ssl-0.3.9.jar org.apache.commons.ssl.KeyStoreBuilder $challenge_password yourfile.pfx`
Successfuly wrote: []

The result is a keystore file named where is whatever the CN is the bottom-most certificate in your chain. The lone entry in the keystore will be an alias of the same name. You can now use this particular keystore in your application server for ssl and it will present your full chain of certificates to clients.

No comments: