1

Trying to read a PKCS8 private key in PEM format with the following:

private static PrivateKey loadPrivateKey()
        throws IOException, GeneralSecurityException, OperatorCreationException, PKCSException {
    FileReader fileReader = new FileReader(certsRoot + "/pep-client-key.pem");
    PEMParser keyReader = new PEMParser(fileReader);

    JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
    InputDecryptorProvider decryptionProv = new JceOpenSSLPKCS8DecryptorProviderBuilder().build("mypassword".toCharArray());

    Object keyPair = keyReader.readObject();
    PrivateKeyInfo keyInfo;

    if (keyPair instanceof PKCS8EncryptedPrivateKeyInfo) {
        keyInfo = ((PKCS8EncryptedPrivateKeyInfo) keyPair).decryptPrivateKeyInfo(decryptionProv); // Exception thrown from here
        keyReader.close();
        return converter.getPrivateKey(keyInfo);
    }
    return null;
}

generates this error:

org.bouncycastle.pkcs.PKCSException: unable to read encrypted data: 1.2.840.113549.1.5.13 not available: Cannot find any provider supporting 1.2.840.113549.3.7
    at org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(Unknown Source)

I've checked with OpenSSL that the file can be processed as PKCS8 PEM, with the password provided.

Any idea? I don't mind if there is a solution not involving BouncyCastle's libraries.

lilezek
  • 6,976
  • 1
  • 27
  • 45

1 Answers1

6

1.2.840.113549.3.7 is the OID for DES-EDE3-CBC-Pad (in PBES2) in PKCS5 = rfc2898 sec B.2.2. (1.2.840.113549.1.5.13 is the 'outer' OID for all PBES2 variants.)

The Sun-now-Oracle (default) providers do support the DES-EDE3 algorithm (aka TripleDES or TDEA keying option 1) with CBC and PKCS5/7 padding but do not have this OID mapping for it. The BouncyCastle provider does have the mapping, so if you use the BC provider for this operation it should work. This can be done

  • for all JVMs by configuring security.provider.<i> in JRE/lib/security/java.security (update: in j9+ JRE/conf/security/java.security) or
  • for a JVM by java.lang.security.Provider.addProvider (new BouncyCastleProvider()) or
  • for this operation by adding .setProvider() with the name of or object for the BC provider to your JceOpenSSLPKCS8DecryptorProviderBuilder invocation

Note BC for TripleDES seems to require the 'unlimited strength policy' on Oracle Java below j8u151; see Cannot open PKCS12 store because of password and InvalidKeyException Illegal key size and many other dupes.

Community
  • 1
  • 1
dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70
  • I am facing the same problem. I am settting as you said but in my case it only happening when runing from outside of the intelij IDE. My enviroment has several restrictions to set those configurations to all JVM. any help !? – Herbert Pimentel Jan 17 '19 at 23:00
  • @HerbertPimentel: you don't say which method you tried, but if it's in the code (my 2nd or 3rd bullet) it should work as long as the BCprov jar is available, which depends on where you put the jar and how you set the classpath. And of course as long as you're running the correct class files; complicated IDEs can sometimes be running something other than what you think. – dave_thompson_085 Jan 19 '19 at 06:07