以 PEM 格式读取 PKCS8:找不到提供程序
Reading PKCS8 in PEM format: Cannot find provider
正在尝试使用以下内容读取 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 变体的 'outer' OID。)
Sun-now-Oracle (默认)提供商 支持 DES-EDE3 算法(也称为 TripleDES 或 TDEA 键控选项 1),带有 CBC 和 PKCS5/7 填充但是没有这个 OID 映射。 BouncyCastle 提供程序确实有映射,因此如果您将 BC 提供程序用于此操作,它应该可以工作。这可以做到
- 通过在
JRE/lib/security/java.security
中配置 security.provider.<i>
(更新:在 j9+ JRE/conf/security/java.security
中)或
- 对于 JVM
java.lang.security.Provider.addProvider (new BouncyCastleProvider())
或
- 通过将
.setProvider()
与 BC 提供程序的名称或对象添加到您的 JceOpenSSLPKCS8DecryptorProviderBuilder
调用中来实现此操作
注意 TripleDES 的 BC 似乎需要 Oracle Java 上的 'unlimited strength policy' below j8u151;见 and InvalidKeyException Illegal key size 和许多其他骗局。
正在尝试使用以下内容读取 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 变体的 'outer' OID。)
Sun-now-Oracle (默认)提供商 支持 DES-EDE3 算法(也称为 TripleDES 或 TDEA 键控选项 1),带有 CBC 和 PKCS5/7 填充但是没有这个 OID 映射。 BouncyCastle 提供程序确实有映射,因此如果您将 BC 提供程序用于此操作,它应该可以工作。这可以做到
- 通过在
JRE/lib/security/java.security
中配置security.provider.<i>
(更新:在 j9+JRE/conf/security/java.security
中)或 - 对于 JVM
java.lang.security.Provider.addProvider (new BouncyCastleProvider())
或 - 通过将
.setProvider()
与 BC 提供程序的名称或对象添加到您的JceOpenSSLPKCS8DecryptorProviderBuilder
调用中来实现此操作
注意 TripleDES 的 BC 似乎需要 Oracle Java 上的 'unlimited strength policy' below j8u151;见