java - 读取 PEM 格式的 PKCS8 : Cannot find provider

标签 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;
}

生成此错误:

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)

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

有什么想法吗?我不介意是否有不涉及 BouncyCaSTLe 库的解决方案。

最佳答案

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 提供程序用于此操作,它应该可以工作。这是可以做到的

  • 通过配置所有 JVM security.provider.<i>JRE/lib/security/java.security (更新:在 j9+ JRE/conf/security/java.security 中)或
  • 用于 JVM by java.lang.security.Provider.addProvider (new BouncyCastleProvider())
  • 为此操作添加 .setProvider()将 BC 提供商的名称或对象添加到您的 JceOpenSSLPKCS8DecryptorProviderBuilder调用

注意 TripleDES 的 BC 似乎需要在 j8u151 以下的 Oracle Java 上使用“无限强度策略”;见Cannot open PKCS12 store because of passwordInvalidKeyException Illegal key size和许多其他骗局。

关于java - 读取 PEM 格式的 PKCS8 : Cannot find provider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46767281/

相关文章:

c# - RSA SHA256 签名生成和验证

java - 从坐标创建椭圆曲线点对象

java - DATETIME 和 DATETIME() 有什么区别

java - 如何使用深度优先搜索 (DFS) 检测有向图中的多个重叠循环?

java - 如果我们在生产环境中部署基于 JDK 1.6.0.35 构建的 war 文件会有什么影响吗?

java - 为什么CMS Final Remark中ParNew,sys time这么长?

Java InputStream 大小

java - 自生成的公钥确实具有相同的开头

java - 在 Linux 上运行的 Java 应用程序中使用 PGP 兼容的文件加密的推荐解决方案?

java - Java字符串的PGP加密