Java – How do i read the private key in java from a pfx certificate

javaopensslpemprivate-keySecurity

I am trying to read a private key i java .I learned inorder to do that i have to extract private key from my full certificate in pfx format.
I have tried the below open ssl command to convert pfx to pem and then to pk8 , but when i tried to read the key in java , it says invalid key format

convert pfx to pem

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

Removing password protection

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

Convert pem to pk8

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

In the java code

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

I am getting an java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format

Can any one help

Best Answer

I think the trick is to do a little bit with openssl and then get keytool to do all the real work. So with openssl convert your existing certificate and key into a PKCS12 file. Using openssl you'd have something like.

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

And then the magic is to import the .p12 into your keystore as if it was another keystore.

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

You have options for using this within java but I would expect a full answer to involve the following.

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

Hope it works!