¿Cómo leo la clave privada en Java desde un certificado pfx?

Estoy tratando de leer una clave privada en Java. Aprendí que para hacerlo tengo que extraer la clave privada de mi certificado completo en formato pfx. Probé el siguiente comando ssl abierto para convertir pfx a pem y luego a pk8, pero cuando traté de leer la clave en java, dice formato de clave no válido

convertir pfx a pem

      openssl pkcs12 -in C:\Documents\xbox-token\conversion\xbox
  token-FullCert.pfx -nocerts -out C:\Documents\xbox-token\conversion\xboxkey.pem

Eliminación de la protección con contraseña

openssl rsa -in C:\Documents\xbox-token\conversion\xboxkey.pem  -out C:\Documents\xbox-token\conversion\xboxkey.pem

Convertir pem a pk8

openssl pkcs8 -topk8 -in C:\Documents\xbox-token\conversion\xboxkey.pem -out C:\Documents\xbox-token\conversion\xboxprv.pk8

en el codigo java

  byte[] encodedPrivateKey=null;
    File privateKeyFile = new File("C:/Documents/xbox-token/conversion/xboxprv.pk8");
    FileInputStream inputStreamPrivateKey = null;
    try {
        inputStreamPrivateKey = new FileInputStream(privateKeyFile);
          encodedPrivateKey = new byte[(int)privateKeyFile.length()];
            inputStreamPrivateKey.read(encodedPrivateKey);
            inputStreamPrivateKey.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    // Create the private key.
    PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
    System.out.println(encodedPrivateKey);
    System.out.println(privateKeySpec);
    RSAPrivateKey privateKey = null;
    try {
        privateKey = (RSAPrivateKey)KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);
    } catch (InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Recibo una java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: formato de clave no válido

Alguien puede ayudar

preguntado el 10 de septiembre de 12 a las 22:09

Encontré la respuesta para esto en la siguiente publicación. stackoverflow.com/questions/7525679/… -

2 Respuestas

Creo que el truco es hacer un poco con openssl y luego hacer que keytool haga todo el trabajo real. Entonces, con openssl, convierta su certificado y clave existentes en un archivo PKCS12. Usando openssl tendrías algo como.

openssl pkcs12 \
  -export -in cert.crt \
  -inkey cert.key \
  -certfile ica.crt \
  -name "yourKey" \
  -out cert.p12

Y luego la magia es importar el .p12 a su almacén de claves como si fuera una alternativa... almacén de claves.

$JAVA_HOME/bin/keytool \
  -importkeystore -deststorepass secret \
  -destkeypass secret -destkeystore $KEYSTORE \
  -srckeystore cert.p12 \
  -srcstoretype PKCS12 \
  -srcstorepass secret \
  -alias "yourKey"

Tiene opciones para usar esto dentro de Java, pero esperaría una respuesta completa que involucre lo siguiente.

import java.security.KeyStore;
KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File("/your/keystore"));
trustStore.load(instream, "secret".toCharArray());

¡Espero que funcione!

Respondido el 10 de Septiembre de 12 a las 23:09

Pero lo necesito como p8 no como p12. El programa que agregué es solo una parte. Lo necesito en formato p8 porque necesito usar la clave para hacer un descifrado saml - Viveek Sankar

Dado que no especifica un formato de salida para sus comandos OpenSSL, obtendrá un archivo codificado con PEM. Java esperará la codificación DER. En lugar de su última llamada de openssl, intente:

openssl pkcs8 -topk8 -inform=PEM -outform=DER
              -in C:\Documents\xbox-token\conversion\xboxkey.pem 
              -out C:\Documents\xbox-token\conversion\xboxprv.pk8

El parámetro '-inform' no debería ser obligatorio (parece ser el predeterminado), pero probablemente sí lo sea el '-outform'.

Si desea verificar qué formato tiene: los archivos PEM son ASCII (codificados en Base64), los archivos DER son binarios. Si a su editor de texto le gusta, probablemente a Java no.

Respondido el 09 de enero de 13 a las 05:01

Lea el contenido pem con líneas "--" y decodifique en Base64. java.util.Base64.getDecoder().decode(pemWithoutHyphenLines) - Venkateswara Rao

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.