javacryptographybouncycastlepemder

How read a PKCS8 encrypted Private key which is also encoded in DER with bouncycastle?


I have tried answers of these questions:

Bouncy Castle : PEMReader => PEMParser

Read an encrypted private key with bouncycastle/spongycastle

However as my encrypted key is encoded in DER when I call

Object object = pemParser.readObject(); 

object is null.

I can convert it to PEM with this openssl's command (it decrypts the key too)

openssl pkcs8 -inform der -in pkey.key -out pkey.pem 

but I need to read the key in its original file


Solution

  • Both those Qs are about parsing, and decrypting, files using OpenSSL's 'legacy PEM' encryption. You are using PKCS8 encryption which is different though similar, so Reading PKCS8 in PEM format: Cannot find provider is closer. You can use most of the approach there, but skipping the PEM parse:

    import org.bouncycastle.asn1.ASN1Sequence;
    import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; // NOT the 
    import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;       // javax ones!
    import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
    import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
    import org.bouncycastle.operator.InputDecryptorProvider;
    import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
    
        // args[0] = filename args[1] = password
        FileInputStream fis = new FileInputStream(args[0]);
        byte[] buff = new byte[9999]; int len = fis.read(buff); fis.close();
        // could use File.readAllBytes in j8 but my dev machine is old
    
        // create what PEMParser would have 
        ASN1Sequence derseq = ASN1Sequence.getInstance (Arrays.copyOf(buff,len));
        PKCS8EncryptedPrivateKeyInfo encobj = new PKCS8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo.getInstance(derseq));
        // decrypt and convert key
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        InputDecryptorProvider decryptionProv = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(args[1].toCharArray());
        PrivateKeyInfo keyInfo = encobj.decryptPrivateKeyInfo(decryptionProv);
        PrivateKey key = converter.getPrivateKey(keyInfo);
    
        // now actually use key, this is just a dummy
        System.out.println (key.getAlgorithm());