Skip to content
Advertisement

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

Advertisement

Answer

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