title: Decrypt PEM private (RSA) key with Bouncy Castle
body: <p><strong>Goal</strong>: Extract an RSA private key from an encrypted PEM file. The private key will be used to programmatically sign certs. </p>
  
  <p><strong>Environment</strong>: Java 8 and Bouncy Castle 1.52</p>
  
  <hr>
  
  <h3>Use Bouncy Castle PEMParser (results in PKCSException)</h3>
  
  <pre><code>    //Register BC as a crypto provider
      Security.addProvider(new BouncyCastleProvider());
  
      //Get file handle
      String caPrivateKeyFname = "cakey.pem";
      FileInputStream fis = null;
      try {
          fis = new FileInputStream(caPrivateKeyFname);
      } catch (FileNotFoundException e) {
          e.printStackTrace();
      }
  
      //Load and parse PEM object
      PEMParser pemRd = new PEMParser(new InputStreamReader(fis));
      Object objectInPemFile = pemRd.readObject();
  
      //I do not know why BC loads the file as a PKCS8 object. OpenSSL does not recognize it as such.
      PKCS8EncryptedPrivateKeyInfo keyInfo = (PKCS8EncryptedPrivateKeyInfo) objectInPemFile;
  
      //Decrypt the private key
      String pwd = "secret";
      InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(pwd.toCharArray());
  
      //Next statement raises an exception.
      PrivateKeyInfo privateKeyInfo = keyInfo.decryptPrivateKeyInfo(pkcs8Prov);
  </code></pre>
  
  <hr>
  
  <pre><code>Exception in thread "main" org.bouncycastle.pkcs.PKCSException: unable to read encrypted data: 1.2.840.113549.1.5.13 not available: Illegal key size
      at org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(Unknown Source)
      at org.codice.ddf.certificate.SignedCertificate.main(SignedCertificate.java:67)
  Caused by: org.bouncycastle.operator.OperatorCreationException: 1.2.840.113549.1.5.13 not available: Illegal key size
      at org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder$1.get(Unknown Source)
      ... 2 more
  Caused by: java.security.InvalidKeyException: Illegal key size
      at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
      at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1060)
      at javax.crypto.Cipher.implInit(Cipher.java:809)
      at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
      at javax.crypto.Cipher.init(Cipher.java:1539)
      at javax.crypto.Cipher.init(Cipher.java:1470)
      ... 3 more  
  </code></pre>
  
  <hr>
  
  <h3><strong>* UPDATE *</strong></h3>
  
  <p><code>openssl asn1parse -in cakey.pem</code></p>
  
  <blockquote>
    <p>PBES2 </p>
    
    <p>PBKDF2 </p>
    
    <p>des-ede3-cbc</p>
  </blockquote>
  
  <p>If I understand correctly, DES key length is 64 bits, so 3DES is 192 bit keys.
  However, Java policy limits the length of DES keys to 56 bits, so maximum key length for 3DES is 168 bits.</p>
  
  <p>Switching out the jurisdiction policy files is not an option for me. I think there is a way to decrypt a PKCS8 encrypted private key with Bouncy Castle, but the solution is more involved than setting the provider to BC. </p>
  
  <p><strong>Can anyone point me to an example or provide some reference code?</strong></p>
  
  <p>(Thanks to dave_thompson_085 for his help).</p>