How to use self-signed PEM client certificates in Java

28.1.2013 | 2 minutes of reading time

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

The line

1openssl 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:

1keytool -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 on the keytool line. Giving

1keytool -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:

1System.setProperty("javax.net.ssl.keyStore", "path/to/keystore.jks");
2System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
3System.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:

1openssl 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:

1keytool -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:

1System.setProperty("javax.net.ssl.trustStore", "path/to/truststore.jks");
2System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
3System.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.

share post




Gemeinsam bessere Projekte umsetzen

Wir helfen Deinem Unternehmen

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.