How do I list / export private keys from a keystore? How do I list / export private keys from a keystore? java java

How do I list / export private keys from a keystore?


You can extract a private key from a keystore with Java6 and OpenSSL. This all depends on the fact that both Java and OpenSSL support PKCS#12-formatted keystores. To do the extraction, you first use keytool to convert to the standard format. Make sure you use the same password for both files (private key password, not the keystore password) or you will get odd failures later on in the second step.

keytool -importkeystore -srckeystore keystore.jks \    -destkeystore intermediate.p12 -deststoretype PKCS12

Next, use OpenSSL to do the extraction to PEM:

openssl pkcs12 -in intermediate.p12 -out extracted.pem -nodes

You should be able to handle that PEM file easily enough; it's plain text with an encoded unencrypted private key and certificate(s) inside it (in a pretty obvious format).

When you do this, take care to keep the files created secure. They contain secret credentials. Nothing will warn you if you fail to secure them correctly. The easiest method for securing them is to do all of this in a directory which doesn't have any access rights for anyone other than the user. And never put your password on the command line or in environment variables; it's too easy for other users to grab.


A portion of code originally from Example Depot for listing all of the aliases in a key store:

    // Load input stream into keystore    keystore.load(is, password.toCharArray());    // List the aliases    Enumeration aliases = keystore.aliases();    for (; aliases.hasMoreElements(); ) {        String alias = (String)aliases.nextElement();        // Does alias refer to a private key?        boolean b = keystore.isKeyEntry(alias);        // Does alias refer to a trusted certificate?        b = keystore.isCertificateEntry(alias);    }

The exporting of private keys came up on the Sun forums a couple of months ago, and u:turingcompleter came up with a DumpPrivateKey class to stitch into your app.

import java.io.FileInputStream;import java.security.Key;import java.security.KeyStore;import sun.misc.BASE64Encoder;public class DumpPrivateKey {     /**     * Provides the missing functionality of keytool     * that Apache needs for SSLCertificateKeyFile.     *     * @param args  <ul>     *              <li> [0] Keystore filename.     *              <li> [1] Keystore password.     *              <li> [2] alias     *              </ul>     */    static public void main(String[] args)    throws Exception {        if(args.length < 3) {          throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same than keystore");        }        final String keystoreName = args[0];        final String keystorePassword = args[1];        final String alias = args[2];        final String keyPassword = getKeyPassword(args,keystorePassword);        KeyStore ks = KeyStore.getInstance("jks");        ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());        Key key = ks.getKey(alias, keyPassword.toCharArray());        String b64 = new BASE64Encoder().encode(key.getEncoded());        System.out.println("-----BEGIN PRIVATE KEY-----");        System.out.println(b64);        System.out.println("-----END PRIVATE KEY-----");    }    private static String getKeyPassword(final String[] args, final String keystorePassword)    {       String keyPassword = keystorePassword; // default case       if(args.length == 4) {         keyPassword = args[3];       }       return keyPassword;    }}

Note: this use Sun package, which is a "bad thing".
If you can download apache commons code, here is a version which will compile without warning:

javac -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey.java

and will give the same result:

import java.io.FileInputStream;import java.security.Key;import java.security.KeyStore;//import sun.misc.BASE64Encoder;import org.apache.commons.codec.binary.Base64;public class DumpPrivateKey {     /**     * Provides the missing functionality of keytool     * that Apache needs for SSLCertificateKeyFile.     *     * @param args  <ul>     *              <li> [0] Keystore filename.     *              <li> [1] Keystore password.     *              <li> [2] alias     *              </ul>     */    static public void main(String[] args)    throws Exception {        if(args.length < 3) {          throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same than keystore");        }        final String keystoreName = args[0];        final String keystorePassword = args[1];        final String alias = args[2];        final String keyPassword = getKeyPassword(args,keystorePassword);        KeyStore ks = KeyStore.getInstance("jks");        ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());        Key key = ks.getKey(alias, keyPassword.toCharArray());        //String b64 = new BASE64Encoder().encode(key.getEncoded());        String b64 = new String(Base64.encodeBase64(key.getEncoded(),true));        System.out.println("-----BEGIN PRIVATE KEY-----");        System.out.println(b64);        System.out.println("-----END PRIVATE KEY-----");    }    private static String getKeyPassword(final String[] args, final String keystorePassword)    {       String keyPassword = keystorePassword; // default case       if(args.length == 4) {         keyPassword = args[3];       }       return keyPassword;    }}

You can use it like so:

java -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey $HOME/.keystore changeit tomcat


If you don't need to do it programatically, but just want to manage your keys, then I've used IBM's free KeyMan tool for a long time now. Very nice for exporting a private key to a PFX file (then you can easily use OpenSSL to manipulate it, extract it, change pwds, etc).

https://www.ibm.com/developerworks/mydeveloperworks/groups/service/html/communityview?communityUuid=6fb00498-f6ea-4f65-bf0c-adc5bd0c5fcc

Select your keystore, select the private key entry, then File->Save to a pkcs12 file (*.pfx, typically). You can then view the contents with:

$ openssl pkcs12 -in mykeyfile.pfx -info