以 PEM 格式读取 PKCS8:找不到提供程序

lil*_*zek 1 java bouncycastle

尝试使用以下内容读取 PEM 格式的 PKCS8 私钥:

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;
}
Run Code Online (Sandbox Code Playgroud)

生成此错误:

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)
Run Code Online (Sandbox Code Playgroud)

我已经使用 OpenSSL 检查该文件可以作为 PKCS8 PEM 处理,并提供密码。

任何的想法?我不介意是否有不涉及 BouncyCastle 库的解决方案。

dav*_*085 5

1.2.840.113549.3.7 是PKCS5 = rfc2898 sec B.2.2 中DES-EDE3-CBC-Pad(在 PBES2 中)的OID。(1.2.840.113549.1.5.13 是所有 PBES2 变体的“外部”OID。)

Sun-now-Oracle (默认)提供程序支持带有 CBC 和 PKCS5/7 填充的 DES-EDE3 算法(又名 TripleDES 或 TDEA 键控选项 1),但没有此 OID 映射。BouncyCastle 提供程序确实具有映射,因此如果您使用 BC 提供程序进行此操作,它应该可以工作。这可以
通过配置security.provider.<i>in JRE/lib/security/java.security(update: in j9+ JRE/conf/security/java.security) 或
* 用于 JVM byjava.lang.security.Provider.addProvider (new BouncyCastleProvider())
* 通过将.setProvider()BC 提供程序的名称或对象添加到您的JceOpenSSLPKCS8DecryptorProviderBuilder调用中来为所有 JVM完成

注意对于低于 j8u151 的 Oracle Java,TripleDES 的 BC 似乎需要“无限强度策略”;由于密码InvalidKeyException 非法密钥大小和许多其他欺骗,see无法打开 PKCS12 存储