How to grab the certificate from a website and import it with Java keytool
Monday, 2. November 2009, 16:53:03
This is another one of those things that are impossible to remember.
For the record, the OS I'm using here is Ubuntu Linux, so the commands and paths will be different if you happen to be on Windows (keep googling, I know that a page is out there for you).
Step One is obviously to go grab the certificate from the web server. We'll use openssl, the tool, to dump the security information we need:
Now open the newly created "cert" file in a text editor and remove everything but the blob that looks like this, but with different data in it:
This cleaned up file is now the certificate that you want to import.
Step Two is to find the key-store that your Java installation uses (google will tell you that this file is called "cacerts"):
So I obviously have more than one keystore because I have more that one version of Java installed. I use the "java-6-sun" version by default. The command
Step Three is to finally install this certificate into the keystore. This command ends up doing it for me:
You will be asked for a password to access the keystore. By default, this keystore password is changeit - another thing easily forgotten.
And now your JVM should be able to create secure connections without those pesky SSL exceptions.
For the record, the OS I'm using here is Ubuntu Linux, so the commands and paths will be different if you happen to be on Windows (keep googling, I know that a page is out there for you).
Step One is obviously to go grab the certificate from the web server. We'll use openssl, the tool, to dump the security information we need:
$ openssl s_client -connect that-server.com:443 > cert
Now open the newly created "cert" file in a text editor and remove everything but the blob that looks like this, but with different data in it:
-----BEGIN CERTIFICATE----- MIIDIjCCAougAwIBAgIQbt4NlJn3RTPdEpf8Qqk74TANBgkqhkiG9w0BAQUFA8Bn [... etc, etc, etc ...] byB0lP6qDtnVOyEQp2Vx+QIJza6IQ4XIglhwMO4V8z12Hi5Fprw= -----END CERTIFICATE-----
This cleaned up file is now the certificate that you want to import.
Step Two is to find the key-store that your Java installation uses (google will tell you that this file is called "cacerts"):
$ locate cacerts /etc/java-1.5.0-sun/security/cacerts /etc/java-6-openjdk/security/cacerts /etc/java-6-sun/security/cacerts
So I obviously have more than one keystore because I have more that one version of Java installed. I use the "java-6-sun" version by default. The command
$ update-alternatives --display javawill tell you which version is your default.
Step Three is to finally install this certificate into the keystore. This command ends up doing it for me:
$ sudo keytool -importcert -keystore /etc/java-6-sun/security/cacerts -alias that-server -file cert
You will be asked for a password to access the keystore. By default, this keystore password is changeit - another thing easily forgotten.
And now your JVM should be able to create secure connections without those pesky SSL exceptions.



Anonymous # 27. November 2009, 13:25
[Sorry for writing this in plain text, apparently HTML/bbcode is turned off for me.]
After you take these steps (thanks!), you may get a different -- but equally annoying -- error message:
"HTTPS hostname wrong: should be "
This should solve the problem:
http://stackoverflow.com/questions/1168969/javas-keytool-command-with-ip-addresses/1169023#1169023
If you're using Clojure, rather than click that last link, simply evalute:
(javax.net.ssl.HttpsURLConnection/setDefaultHostnameVerifier
(proxy [javax.net.ssl.HostnameVerifier] []
(verify [a b] true)))
Then it should work.
Incidentally, if you're using clojure.contrib.http.agent, you might get a maddeningly opaque error message like "Agent has errors". I find this is sufficient to get a decent error message, to better know what it is Java is complaining about:
(.getInputStream (.openConnection (java.net.URL. "https://your-domain.com")))