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 { 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;
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