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:
- key - www_yourdomain_com.key
- certificate - www_yourdomain_com.crt
- 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.
- We build intermediate keystore in PKCS12 format using the key and certificate (including intermediate certifciates).
# 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
- We then convert this store into a Java key store:
# keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 \
-srcstorepass changeit -deststorepass changeit -destkeypass changeit \
-destkeystore keystore -alias 1 -destalias tomcat
- Now we modify HTTPS connector in Tomcat's conf/server.xml to read:
<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
- A (might be temporary) password is needed for destination store and key to avoid a null reference exception at import step
- We use 'alias 1' for keytool to correcty find our certificate/key in
keystore.p12
- Choose your own destination password
- You may import CA/intermediate certificates separately later instead of doing it in one bundle with website certificate like in above example (start with CA cert and go down)
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:
- Extract PEM format private key from Java keystore:
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
- Get PEM key out of PKCS12 (password entered in step 1 may be needed)
openssl pkcs12 -in keystore.p12 -out extracted.pem -nodes
Enter Import Password:
MAC verified OK
- Cut the private key and save to a key file:
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?