Keytool cacert extraction

From ConShell
Jump to: navigation, search

Before you spend alot of time on this, see the easy way.

Sometimes you need to have a PEM format CA certificate available for trust verification in certain apps like postfix or apache. If you have java installed, you most likely have a cacerts file that came with it. Mine is in /usr/java/j2re1.4.2_07/lib/security/cacerts

Problem is, the cacerts file is a JKS keystore, stored in a format unreadable to non-java applications. So I will show how to use keytool and openssl to extract and convert a single CA certificate (alias verisignserverca) to PEM format, which CAN usually be read.

First, figure out which ca certificate you need. This is usually a matter of identifying the subject (also called DN or distinguished name) of the issuers certificate. In my case the subject was unknown... all I had was a message in the postfix log saying:

May 13 22:10:02 localhost postfix/smtp[22102]: setting up TLS connection to
May 13 22:10:02 localhost postfix/smtp[22102]: verify error:num=19:self signed certificate in certificate chain
May 13 22:10:02 localhost postfix/smtp[22102]: Peer certificate could not be verified

Since the connection was clearly to, I use openssl to get the issuer.

openssl s_client -connect -starttls smtp

The relevant output is in the Certificate chain section of the output. I see this;

0 s:/C=US/ST=New Jersey/L=Middletown/O=AT&T/OU=for Comcast/
  i:/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
1 s:/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
  i:/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority <-- Issuing Certificate Authority!!

I want to find the corresponding certificate in the cacerts keystore so as to get the alias used.

keytool -keystore /usr/java/j2re1.4.2_07/lib/security/cacerts -v -list

The password is normally blank so just press enter...or try "changeme". Look for the corresponding certificate. Hint: Alot of output so redirect to a file or pipe to less.

Alias name: verisignserverca <-- This is what we need for extraction
Creation date: Jun 29, 1998
Entry type: trustedCertEntry

Owner: OU=Secure Server Certification Authority, O="RSA Data Security, Inc.", C=US
Issuer: OU=Secure Server Certification Authority, O="RSA Data Security, Inc.", C=US
Serial number: 2ad667e4e45fe5e576f3c98195eddc0
Valid from: Tue Nov 08 16:00:00 PST 1994 until: Thu Jan 07 15:59:59 PST 2010
Certificate fingerprints:
         MD5:  74:7B:82:03:43:F0:00:9E:6B:B3:EC:47:BF:85:A5:93
         SHA1: 44:63:C5:31:D7:CC:C1:00:67:94:61:2B:B6:56:D3:BF:82:57:84:6F

Once the alias has been identified we can do the extraction.

keytool -keystore /usr/java/j2re1.4.2_07/lib/security/cacerts -export -alias verisignserverca > /tmp/verisign.cacert

The result is a DER (binary) formatted certificate in /tmp/verisign.cacert. It can be viewed using:

openssl x509 -noout -text -in /tmp/verisign.cacert -inform der

You will want to convert it to another format - PEM - which is more widely used in applications such as apache and postfix.

openssl x509 -out /tmp/verisign-cacert.pem -outform pem -text -in /tmp/verisign.cacert -inform der

The resulting file can now be referenced from apache, postfix, etc as the CA certificate.

Important update! 2005-May-20

It appears there is a much easier way to do this, as usual the openssl toolkit is the solution. By running the following command, the PEM format certificate chain will be displayed on STDOUT.

openssl s_client -connect -starttls smtp -showcerts

The last certificate in the chain is the CA (issuer) cert. This can be pasted into a text file and named according to the output of the openssl hash command (see above).

Extracting a PEM certificate from .jks file in one command

This can be done by using the -rfc flag which will cause the key to be printed in a readable form. So the original command:

keytool -keystore /usr/java/j2re1.4.2_07/lib/security/cacerts -export -alias verisignserverca > /tmp/verisign.cacert


keytool -keystore /usr/java/j2re1.4.2_07/lib/security/cacerts -export -alias verisignserverca -rfc -file /tmp/verisign.cacert

Also notice that the -file option can be used instead of a redirect.

Finally, you can use the -storepass option to specify the password on the command line. While this is potentially a violation of security the convenience usually outweighs the remote possibility of someone capturing the command line before it completes. The final command would be:

 keytool -keystore /usr/java/j2re1.4.2_07/lib/security/cacerts -export -alias verisignserverca -rfc -file /tmp/verisign.cacert -storepass changeme