Keytool cacert extraction
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 smtp.comcast.net 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 smtp.comcast.net, I use openssl to get the issuer.
openssl s_client -connect smtp.comcast.net:25 -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/CN=smtp.comcast.net 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 smtp.comcast.net:25 -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
becomes
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