¿Cómo puedo listar / exportar claves privadas desde un almacén de claves?

¿Cómo puedo listar y exportar una clave privada de un almacén de claves?

Una porción de código originaria de Example Depot para listar todos los alias en un almacén de claves:

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

La exportación de claves privadas surgió en los foros de Sun hace un par de meses, y tú: turingcompleter creó una clase DumpPrivateKey para agregar a tu aplicación.

 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 
    *
  • [0] Keystore filename. *
  • [1] Keystore password. *
  • [2] alias *
*/ static public void main(String[] args) throws Exception { if(args.length < 3) { throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias,

Nota: esto usa el paquete Sun, que es "malo" .
Si puede descargar el código de apache commons , aquí hay una versión que comstackrá sin previo aviso:

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

y dará el mismo resultado:

 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 
    *
  • [0] Keystore filename. *
  • [1] Keystore password. *
  • [2] alias *
*/ static public void main(String[] args) throws Exception { if(args.length < 3) { throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias,

Puedes usarlo así:

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

Puede extraer una clave privada de un almacén de claves con Java6 y OpenSSL. Todo esto depende del hecho de que tanto Java como OpenSSL son compatibles con los almacenes de claves con formato PKCS # 12. Para realizar la extracción, primero usa keytool para convertir al formato estándar. Asegúrese de utilizar la misma contraseña para ambos archivos (contraseña de clave privada, no contraseña de almacén de claves) u obtendrá errores ocasionales más adelante en el segundo paso.

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

Luego, use OpenSSL para hacer la extracción a PEM:

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

Debería poder manejar ese archivo PEM con bastante facilidad; es texto sin formato con una clave privada no encriptada codificada y certificado (s) dentro de ella (en un formato bastante obvio).

Cuando haga esto, tenga cuidado de mantener seguros los archivos creados. Contienen credenciales secretas. Nada le advertirá si no puede asegurarlos correctamente. El método más fácil para protegerlos es hacer todo esto en un directorio que no tiene ningún derecho de acceso para nadie más que el usuario. Y nunca coloque su contraseña en la línea de comando o en variables de entorno; es demasiado fácil de atrapar para otros usuarios.

Si no necesita hacerlo programáticamente, sino que solo desea administrar sus claves, entonces he usado la herramienta gratuita KeyMan de IBM durante mucho tiempo. Muy bueno para exportar una clave privada a un archivo PFX (entonces puedes usar OpenSSL fácilmente para manipularlo, extraerlo, cambiar pwds, etc.).

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

Seleccione su almacén de claves, seleccione la entrada de la clave privada, luego Archivo-> Guardar en un archivo pkcs12 (* .pfx, por lo general). A continuación, puede ver los contenidos con:

$ openssl pkcs12 -en mykeyfile.pfx -info

Aquí hay una versión más corta del código anterior, en Groovy. También tiene una encoding base64 incorporada:

 import java.security.Key import java.security.KeyStore if (args.length < 3) throw new IllegalArgumentException('Expected args:     ') 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-----" 

Para el desarrollo de Android, para convertir el almacén de claves creado en eclipse ADT en clave pública y clave privada utilizada en SignApk.jar:

exportar clave privada:

 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 

edite private.rsa.pem y deje “—– BEGIN PRIVATE KEY —–” to “—– END PRIVATE KEY —–” paragraph, luego:

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

exportar clave pública:

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

firmar apk:

 java -jar SignApk.jar public.x509.der private.rsa.der input.apk output.apk 

Esta pregunta surgió en stackexchange security, una de las sugerencias fue usar Keystore explorer

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

Después de haberlo probado, funciona realmente bien y lo recomiendo encarecidamente.

Primero que nada, ¡ten cuidado! Toda su seguridad depende de … e … la privacidad de sus claves privadas. Keytool no tiene exportada la clave incorporada para evitar la divulgación accidental de este material sensible, por lo que es posible que desee considerar algunas protecciones adicionales que podrían implementarse para proteger sus claves exportadas.

Aquí hay un código simple que le da PKCS # 8 PrivateKeyInfo sin cifrar que puede ser utilizado por OpenSSL (vea la opción -nocrypt de su utilidad pkcs8 ):

 KeyStore keys = ... char[] password = ... Enumeration 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(); } } } 

Si necesita otros formatos, puede usar KeyFactory para obtener una especificación de clave transparente para diferentes tipos de claves. Luego puede obtener, por ejemplo, el exponente privado de una clave privada de RSA y enviarla en el formato que desee. Eso sería un buen tema para una pregunta de seguimiento.

Otra gran herramienta es KeyStore Explorer: http://keystore-explorer.sourceforge.net/

Otra forma menos convencional pero posiblemente más fácil de hacer esto es con JXplorer . Aunque esta herramienta está diseñada para explorar directorios LDAP, tiene una GUI fácil de usar para manipular almacenes de claves. Una de esas funciones en la GUI puede exportar claves privadas desde un almacén de claves JKS.