Private Key and Certificate Reuse Across Java Keystores and OpenSSL

This topic provides a quick tutorial on exporting/importing private keys for reuse from a Java keystore to OpenSSL and vice versa. Regardless of the procedure followed to create host private keys and certificates, sometimes it becomes necessary to reuse those private keys and certificates by other services on the same host. For example, if you used OpenSSL to create private keys and certificates for a service, you can reuse those keys for a Java-based service on the same host by converting them to the Java keystore format.

The documentation for Configuring TLS Security for Cloudera Manager describes both approaches to creating private keys, using Java keystore, and OpenSSL.

Why Reuse a Private Key?

Certificate authorities generally revoke previous generations of certificates issued to a host. Hence, a host cannot have 2 sets of CA-issued certificates and have both be valid. Once a certificate is issued to a host, it then becomes necessary to reuse the private key that requested the certificate, and the CA-issued certificate across different services, Java-based and otherwise.

Conversion from Java Keystore to OpenSSL

First, use keytool to export the private key and certificate to a PKCS12 file as a transitional file format that can then be split up into individual key and certificate files by the openssl command line. Replace cmhost and hostname in the commands below with the actual hostname of the server that is managing the certificate and keys.
$ keytool -importkeystore -srckeystore /opt/cloudera/security/jks/hostname-keystore.jks \ 
-srcstorepass password -srckeypass password -destkeystore /tmp/hostname-keystore.p12 \ 
-deststoretype PKCS12 -srcalias hostname -deststorepass password -destkeypass password
Now use openssl to split the PKCS12 file created above into first, the certificate file, and then the private key file. While the CA-issued certificate can be used as is, the command has been provided here for completeness.
$ openssl pkcs12 -in /tmp/hostname-keystore.p12 -passin pass:password  -nokeys \
-out /opt/cloudera/security/x509/hostname.pem

$ openssl pkcs12 -in /tmp/hostname-keystore.p12 -passin pass:password -nocerts \
-out /opt/cloudera/security/x509/hostname.key -passout pass:password
Note that the method above generates a key with a password. For services such as Impala and Hue that accept keys without passwords, you can use the following command:
$ openssl rsa -in /opt/cloudera/security/x509/hostname.key \
-passin pass:password -out /opt/cloudera/security/x509/hostname.pem

Conversion from OpenSSL to Java Keystore

First, convert the openssl private key and certificate files into a PKCS12 file. The PKCS12 file can then be imported into a Java keystore file. Replace hostname in the commands below with the FQDN for the host whose certificate is being imported.
$ openssl pkcs12 -export -in /opt/cloudera/security/x509/hostname.pem \
-inkey /opt/cloudera/security/x509/hostname.key -out /tmp/hostname.p12 \
-name hostname -passin pass:password -passout pass:password

$ keytool -importkeystore -srckeystore /tmp/hostname.p12 -srcstoretype PKCS12 \ 
-srcstorepass password -alias hostname -deststorepass password 
-destkeypass password -destkeystore /opt/cloudera/security/jks/hostname-keystore.jks