PEM files containing self-signed client certificates and a certificate chain cannot be directly imported into a Java Key Store (JKS). In order to use these certificates with the SUN keystore provider (JKS keystore type) the PEM file must be imported into a PKCS12 keystore first using openssl. The PKCS12 keystore can then be imported into a JKS keystore using Java’s keytool.
Create JKS keystore with private key and certificate chain
openssl pkcs12 -export -out keystore.p12 -inkey MyCertificate.pem -in MyCertificate.pem
will import the private certificate and all chain certificates into a new PKCS12 keystore “keystore.p12”. It is crucial to provide a keystore password when openssl asks for an export password. Otherwise keytool will not be able to read the private key in the next step. Using keytool this PKCS12 keystore can be imported into a JKS keystore:
keytool -importkeystore -destkeystore keystore.jks -srcstoretype PKCS12 -srckeystore certificate.p12
After providing passwords for the source and destination keystore the client certificate including all chain certificates is imported into the JKS keystore “keystore.jks”. The default alias is “1”. It can be altered with the command line option -destalias <your_alias_here> on the keytool line. Giving
keytool -list -keystore keystore.jks
shows one entry as “PrivateKeyEntry” which is essential for client certificates. With an additional -v option it shows the whole certificate chain, which is the private key followed by intermediate certificates and the root signing certificate. When using the client certificate for SSL connections the new keystore must be configured like this:
System.setProperty("javax.net.ssl.keyStore", "path/to/keystore.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "changeit"); System.setProperty("javax.net.ssl.keyStoreType", "JKS");
Java is also able to read PKCS12 keystores. The “javax.net.ssl.keyStoreType” will then be configured with “PKCS12” giving the keystore file originated from openssl.
Create JKS truststore with public server certificate
In order to use the self-signed client certificate which was issued by a non public CA the public server certificate must be imported into a truststore. The intermediate keystore.p12 is a good point to extract only the CA certificates:
openssl pkcs12 -in keystore.p12 -cacerts -nokeys -out chain.pem
will export the CA certificates into “chain.pem”. keytool can now import the certificate into a new truststore:
keytool -importcert -trustcacerts -file chain.pem -keystore chain.jks
The new “chain.jks” may even be the previously created “keystore.jks” to have everything in one place. Just like the keystore the custom truststore must be configured:
System.setProperty("javax.net.ssl.trustStore", "path/to/truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); System.setProperty("javax.net.ssl.trustStoreType", "JKS");
Just like for keystores Java is able to handle the PKCS12 format here using the SunJSSE provider. Be careful if your Java app also makes connections to public trusted servers: the given truststore is exclusive so all CAs known to Java (in lib/security/cacerts) are not available now. You must add them to your custom truststore to have them available.