Published on Feb 1 2013 in Java Tomcat

Easy method for importing PEM key and certificates into Java keystore with JDK6+.

In this tutorial we have x509 PEM OpenSSL certifcate used in Apache2 and related private key. Now we want to use them directly in Tomcat by importing them into Java keystore. This situation differs from the case when you generate key using keytool.

What we have:

  1. key - www_yourdomain_com.key
  2. certificate - www_yourdomain_com.crt
  3. intermediate cetificates bundle - www_yourdomain_com_intermediate.crt

JDK6 keytool allows for quite easy import procedure. It was more complicated with previous JDK version. Let's go.

# cat www_yourdomain_com.crt www_yourdomain_com_intermediate.crt > www_yourdomain_com_all.crt
# openssl pkcs12 -export -in www_yourdomain_com_all.crt -inkey www_yourdomain_com.key \
        -passout pass:changeit > keystore.p12
# keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 \
    -srcstorepass changeit -deststorepass changeit -destkeypass changeit \ 
    -destkeystore keystore -alias 1 -destalias tomcat
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
     maxThreads="150" scheme="https" secure="true"
     keystoreFile="${catalina.base}/keystore" keystorePass="changeit"
     keyAlias="tomcat" clientAuth="false" sslProtocol="TLS" />

Notes

If you are using APR (Apache Portable Runtime) to increase performance then you do not use keystore format. Instead you use the original certificates and key in PEM format (OpenSSL).

<Connector port="443" scheme="https" secure="true" SSLEnabled="true" URIEncoding="UTF-8" protocol="org.apache.coyote.http11.Http11AprProtocol"
      SSLCertificateFile="${catalina.base}/domain.com.crt"
      SSLCertificateKeyFile="${catalina.base}/domain.com.key"
      SSLPassword=""
      SSLVerifyClient="none"
      SSLCertificateChainFile="${catalina.base}/domain.com.cacrt"
      SSLCipherSuite="ALL:!ADH:!SSLv2:!EXP:!LOW:!aNULL:!eNULL:!MD5:!RC4"
      SSLProtocol="TLSv2"
      compression="on"
      compressableMimeTypes="application/json,text/html,text/css,text/plain,application/javascript" />

Order of certificates in certificate bundle

In case you have more than 1 intermediate certificate you should concatenate them starting with lowest level. For example in PositiveSSL certificate set the PositiveSSLCA2.crt is more important (closer to top-level CA or top-level CA itself) so it comes after lower level certificate AddTrustExternalCARoot.crt in the command. If you want to add your site's certificate to this chain it should go first.

cat AddTrustExternalCARoot.crt PositiveSSLCA2.crt > intermediate.crt

Extracting PEM format key from Java keystore

It may be that you want to switch to APR library and so you want key in PEM format but you only have it stored in Java keystore. It can be extracted with below commands:

keytool -importkeystore -srckeystore keystore -destkeystore keystore.p12 -deststoretype PKCS12
Enter destination keystore password: 
Re-enter new password: 
Enter source keystore password: 
Problem importing entry for alias www.java-and-ssl.com: java.security.KeyStoreException: TrustedCertEntry not supported.
Entry for alias www.java-and-ssl.com not imported.
Do you want to quit the import process? [no]: no
Import command completed: 1 entries successfully imported, 1 entry failed or cancelled
openssl pkcs12 -in keystore.p12 -out extracted.pem -nodes
Enter Import Password:
MAC verified OK
sed '/PRIVATE KEY/, /PRIVATE KEY/!d' extracted.pem > key.pem
cat key.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAq2vEpLJfqdQZacD6LDrtMG6ev7qh6IIp8PEzehWB1IsntSY0
...
sx6u7NwyhnEU8bP6O0PosOC9Aj9Qo4AWjF96bVY5pyWZrbsV/Ii0 
-----END RSA PRIVATE KEY-----

Now you can go to the beginning of this tutorial and follow instructions on building your Java keystore with PEM format key, website certificate and intermediate/CA certificates bundle or directly use the set of files with APR and Tomcat as shown above.

References: How to use SSL certificates with Java, Tomcat and cPanel?