4

I am new to BouncyCastle. I have a private key generated using the below code.

     final CertAndKeyGen keypair = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
     keypair.generate(1024);
     final PrivateKey privKey = keypair.getPrivateKey();

I would to encrypt it with a password using AES or some openssl supported algorithm using BouncyCastle. I am trying to find where to start, since I am not able to find any good tutorial on this.

halfer
  • 19,824
  • 17
  • 99
  • 186
Lolly
  • 34,250
  • 42
  • 115
  • 150
  • Here is an interesting post : https://stackoverflow.com/questions/41180398/how-to-add-a-password-to-an-existing-private-key-in-java – The TRIX Jul 13 '17 at 18:00

2 Answers2

7

If you just want to output your private key to a passphrase "12345" protected PEM formatted and file "privatekey.pem" you can use this BC code:

    JceOpenSSLPKCS8EncryptorBuilder encryptorBuilder = new JceOpenSSLPKCS8EncryptorBuilder(PKCS8Generator.PBE_SHA1_3DES);
    encryptorBuilder.setRandom(EntropySource.getSecureRandom());
    encryptorBuilder.setPasssword("12345".toCharArray());
    OutputEncryptor oe = encryptorBuilder.build();
    JcaPKCS8Generator gen = new JcaPKCS8Generator(privKey,oe);
    PemObject obj = gen.generate();

    PEMWriter pemWrt = new PEMWriter( new FileWriter("privatekey.pem"));
    pemWrt.writeObject(obj);
    pemWrt.close();

then afterwards you can get at the private key with openssl with

$ openssl rsa -in privatekey.pem -check
Enter pass phrase for privatekey.pem:
RSA key ok
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
.....
-----END RSA PRIVATE KEY-----

The "standard" use of PEMWriter will not passphrase protect your private key:(

pjklauser
  • 1,156
  • 11
  • 13
3

If you'd prefer to protect your private keys with AES-256 instead of one of the old DES variants supported by PKCS8, this will work:

public String toPem(String password) throws IOException {

  StringWriter sw = new StringWriter();

  try (JcaPEMWriter pemWriter = new JcaPEMWriter(sw)) {

    PEMEncryptor encryptor =
        new JcePEMEncryptorBuilder("AES-256-CBC").build(password);

    // privateKey is a java.security.PrivateKey
    JcaMiscPEMGenerator gen = new JcaMiscPEMGenerator(privateKey, encryptor);
    pemWriter.writeObject(gen);
  }

  return sw.toString();
}

You can verify the output with openssl. In my case the key is EC so this command is used:

$ openssl ec -in key.txt -passin pass:password -text

Adapt as required for RSA keys.

Andy Brown
  • 11,766
  • 2
  • 42
  • 61