How to list / export private keys from a keystore?

How do I display and export the private key from the keystore?

+57
java ssl keystore
Sep 29 '08 at 19:07
source share
9 answers

Part of the code, originally from the Depot example, to list all the aliases in the keystore:

// 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); } 

Private key export appeared on the Sun forum a couple of months ago, and u: turingcompleter introduced the DumpPrivateKey class for embedding in your application.

 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 tha n 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 uses the Sun package, which is the "bad thing" .
If you can download the apache community code , here is the version that 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 tha n 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 this:

 java -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey $HOME/.keystore changeit tomcat 
+29
Sep 29 '08 at 19:12
source share

You can retrieve the private key from the keystore using Java6 and OpenSSL. It all depends on the fact that both Java and OpenSSL support K-repositories in PKCS # 12 format. To extract, first use keytool to convert to standard format. Make sure you use the same password for both files (private key password, not key store password) , or later you will get odd crashes in the second step.

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

Next, use OpenSSL to perform the extraction in PEM:

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

You should be able to process this PEM file quite easily; it is plain text with an unencrypted private key encoded and certificate (s) inside it (in a fairly obvious format).

When you do this, make sure the files are protected. They contain secret powers. Nothing will warn you if you cannot protect them properly. The easiest way to ensure them is to do all this in a directory that does not have access rights for anyone other than the user. And never enter your password on the command line or in environment variables; It is too easy for other users to capture.

+102
Apr 08 2018-11-11T00:
source share

If you do not need to do this programmatically, but just want to manage your keys, I used IBM keykey KeyMan for a long time. It is very nice to export the private key to a PFX file (then you can easily use OpenSSL to manipulate it, extract it, modify pwds, etc.).

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

Select the keystore, select the private key entry, then File-> Save to pkcs12 file (usually .pfx). Then you can view the contents with:

$ openssl pkcs12 -in mykeyfile.pfx -info

+6
Sep 29 '08 at 19:43
source share

Below is a shorter version of the above code in Groovy. Also has base64 encoding embedded:

 import java.security.Key import java.security.KeyStore if (args.length < 3) throw new IllegalArgumentException('Expected args: <Keystore file> <Keystore format> <Keystore password> <alias> <key password>') def keystoreName = args[0] def keystoreFormat = args[1] def keystorePassword = args[2] def alias = args[3] def keyPassword = args[4] def keystore = KeyStore.getInstance(keystoreFormat) keystore.load(new FileInputStream(keystoreName), keystorePassword.toCharArray()) def key = keystore.getKey(alias, keyPassword.toCharArray()) println "-----BEGIN PRIVATE KEY-----" println key.getEncoded().encodeBase64() println "-----END PRIVATE KEY-----" 
+5
Feb 01 '12 at 23:32
source share

For Android development, to convert the keystore created in eclipse ADT to the public key and private key used in SignApk.jar:

export private key:

 keytool.exe -importkeystore -srcstoretype JKS -srckeystore my-release-key.keystore -deststoretype PKCS12 -destkeystore keys.pk12.der openssl.exe pkcs12 -in keys.pk12.der -nodes -out private.rsa.pem 

edit private.rsa.pem and leave "----- START PRIVATE KEY -----" to "----- END PRIVATE KEY -----", and then:

 openssl.exe base64 -d -in private.rsa.pem -out private.rsa.der 

export public key:

 keytool.exe -exportcert -keystore my-release-key.keystore -storepass <KEYSTORE_PASSWORD> -alias alias_name -file public.x509.der 

apk sign:

 java -jar SignApk.jar public.x509.der private.rsa.der input.apk output.apk 
+4
Nov 29 '11 at 9:59
source share

This question arose from stackexchange security, one suggestion was to use Keystore explorer

https://security.stackexchange.com/questions/3779/how-can-i-export-my-private-key-from-a-java-keytool-keystore

Just by trying it, it works very well and I highly recommend it.

+4
Jun 18 '14 at 13:54 on
source share

First of all, be careful! All your safety depends on & hellip; er & hellip; confidentiality of your private keys. Keytool does not have a key export built-in to prevent accidental disclosure of this sensitive material, so you may want to consider some additional precautions that can be taken to protect your exported keys.

Here is a simple code that gives you unencrypted PKCS # 8 PrivateKeyInfo that OpenSSL can use (see the -nocrypt parameter of its pkcs8 utility ):

 KeyStore keys = ... char[] password = ... Enumeration<String> aliases = keys.aliases(); while (aliases.hasMoreElements()) { String alias = aliases.nextElement(); if (!keys.isKeyEntry(alias)) continue; Key key = keys.getKey(alias, password); if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) { /* Most PrivateKeys use this format, but check for safety. */ try (FileOutputStream os = new FileOutputStream(alias + ".key")) { os.write(key.getEncoded()); os.flush(); } } } 

If you need other formats, you can use KeyFactory to get a transparent key specification for different types of keys. Then you can get, for example, a private copy of the RSA private key and output it in the desired format. This will be a good topic for the next question.

+3
Sep 29 '08 at 19:16
source share

Another great tool is KeyStore Explorer: http://keystore-explorer.sourceforge.net/

+3
Feb 02 '15 at 9:54
source share

Another less traditional, but perhaps easier way to do this is JXplorer . Although this tool is designed to view LDAP directories, it has an easy-to-use graphical interface for managing keystores. One such feature in the GUI can export secret keys from the JKS keystore.

0
Jul 13 2018-12-12T00:
source share



All Articles