英文:
Loading pkcs12 file with BouncyCastle fails on unknown PRF algorithm (hmacWithSHA256)
问题
我们拥有一个由第三方(非我们管理)以 pkcs#12 格式提供的证书。我们必须在将电子邮件发送给这个特定客户之前,使用这个证书对电子邮件进行签名。
旧证书没有任何问题,但是由于即将过期,我们需要将其替换为一个新证书,该证书具有以下密钥加密方案(通过openssl提取):
PBES2、PBKDF2、AES-256-CBC、迭代2000次、PRF hmacWithSHA256
当尝试使用BouncyCastle安全提供程序加载此密钥库时,我们会收到以下错误:
Caused by: java.io.IOException: exception unwrapping private key - java.security.spec.InvalidKeySpecException: Invalid KeySpec: unknown PRF algorithm 1.2.840.113549.2.9
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.unwrapKey(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(Unknown Source)
at java.security.KeyStore.load(KeyStore.java:1445)
at org.obfuscated.SignEmailGenerator.loadKeyStore(SignEmailGenerator.java:130)
代码(为简洁起见,省略了异常处理和其他实用程序代码):
KeyStore keystore = KeyStore.getInstance("PKCS12", BouncyCastleProvider.PROVIDER_NAME);
InputStream trustStoreInputStream = MethodHandles.lookup().lookupClass()
.getResourceAsStream(mailSigningConfiguration.getKeyStorePath());
keystore.load(trustStoreInputStream, mailSigningConfiguration.getKeyStorePassword().toCharArray());
1.2.840.113549.2.9 是 hmacWithSHA256 的 OID,这让我产生了一个问题。Bouncy Castle 是否不支持这个算法?根据 http://www.bouncycastle.org/specifications.html 我猜它应该支持吧?如果它支持,为什么我无法加载这样的文件?
JDK 1.8.0
bcmail-jdk15on 版本 1.66
非常感谢任何形式的帮助。
英文:
we have a certificate in a pkcs#12 format provided by a 3rd party (not managed by us). We must sign emails with this certificate before sending them to this specific customer from our platform.
There were no issues with the old certificate, but as it is about to expire we need to replace it by a newer one, which has following key encryption schema (extracted via openssl):
PBES2, PBKDF2, AES-256-CBC, Iteration 2000, PRF hmacWithSHA256
When trying to load this keystore with bouncycastle security provider we get a following error
Caused by: java.io.IOException: exception unwrapping private key - java.security.spec.InvalidKeySpecException: Invalid KeySpec: unknown PRF algorithm 1.2.840.113549.2.9
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.unwrapKey(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(Unknown Source)
at java.security.KeyStore.load(KeyStore.java:1445)
at org.obfuscated.SignEmailGenerator.loadKeyStore(SignEmailGenerator.java:130)
code (exception handling and other utility code removed for brevity):
KeyStore keystore = KeyStore.getInstance("PKCS12", BouncyCastleProvider.PROVIDER_NAME);
InputStream trustStoreInputStream = MethodHandles.lookup().lookupClass()
.getResourceAsStream(mailSigningConfiguration.getKeyStorePath());
keystore.load(trustStoreInputStream, mailSigningConfiguration.getKeyStorePassword().toCharArray());
The 1.2.840.113549.2.9 is an OID for hmacWithSHA256 which leads me to the question. Does bouncy castle not support this algorithm? Based on http://www.bouncycastle.org/specifications.html I would guess it should? If it does support it, why am I unable to load such file?
Jdk 1.8.0
bcmail-jdk15on version 1.66
Any input is appreciated, thank you.
Edit (private key is part of the file):
c:\Programy\OpenSSL-Win64\bin>openssl pkcs12 -info -in PrivateKey.pfx -nodes -nocerts
Enter Import Password:
MAC: sha256, Iteration 2000
MAC length: 32, salt length: 20
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2000, PRF hmacWithSHA256
Bag Attributes
localKeyID: 01 00 00 00
friendlyName: ---ommited---
Microsoft CSP Name: Microsoft Enhanced Cryptographic Provider v1.0
Key Attributes
X509v3 Key Usage: 10
-----BEGIN PRIVATE KEY-----
-- data is here, but I've ommited it ---
-----END PRIVATE KEY-----
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2000, PRF hmacWithSHA256
Certificate bag
Certificate bag
Certificate bag
</details>
# 答案1
**得分**: 3
遇到了这个问题,正在使用的BouncyCastle提供程序版本是 `1.51`。
服务器日志中的异常为:
```log
2022-01-13 14:28:28,699 ERROR (default task-46) getKeyStore,load. location:xxx.p12 at xxx: java.io.IOException: 在 xxx 处解包私钥时出现异常 - java.security.spec.InvalidKeySpecException: 无效的 KeySpec: 未知的 PRF 算法 1.2.840.113549.2.9
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.unwrapKey(未知来源)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(未知来源)
at java.security.KeyStore.load(KeyStore.java:1445)
通过使用 openssl
检查了 p12 文件。
$> openssl pkcs12 -info -in xxx.p12 -nodes -nocerts
输入导入密码:
MAC:sha1,迭代次数 100000
MAC 长度:20,盐长度:20
PKCS7 数据
Shrouded Keybag:PBES2、PBKDF2、AES-256-CBC、迭代次数 10000、PRF 哈希消息认证码 hmacWithSHA256
Bag 属性
我在另一个使用 BouncyCastle 提供程序版本 1.69
的环境中进行了测试,一切正常。但由于服务器上的提供程序无法升级,我不得不通过 openssl
重新创建 p12 密钥库,以使加密方式与服务器中的一些旧密钥库保持一致,然后问题得以解决。
openssl pkcs12 -export -inkey <private> -in <cert> -name <alias> -out <keystore>.p12
检查重新创建的密钥库信息:
$> openssl pkcs12 -info -in xxx.p12 -nodes -nocerts
输入导入密码:
MAC:sha1,迭代次数 2048
MAC 长度:20,盐长度:8
PKCS7 加密数据:pbeWithSHA1And40BitRC2-CBC,迭代次数 2048
英文:
Encounter this problem today, the BouncyCastle provider in use is 1.51
.
Exception in server log is:
2022-01-13 14:28:28,699 ERROR (default task-46) getKeyStore,load. location:xxx.p12 at xxx: java.io.IOException: exception unwrapping private key - java.security.spec.InvalidKeySpecException: Invalid KeySpec: unknown PRF algorithm 1.2.840.113549.2.9
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.unwrapKey(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(Unknown Source)
at java.security.KeyStore.load(KeyStore.java:1445)
After checked the p12 with openssl
.
$> openssl pkcs12 -info -in xxx.p12 -nodes -nocerts
Enter Import Password:
MAC: sha1, Iteration 100000
MAC length: 20, salt length: 20
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Bag Attributes
I tested it in another environment with BouncyCastle provider 1.69
, worked fine. But due to the provider cannot be upgraded on server, I had to re-created the p12 keystore via openssl
to align the encryption with some old keystores in server, then it worked.
openssl pkcs12 -export -inkey <private> -in <cert> -name <alias> -out <keystore>.p12
Check the re-created keystore info:
$> openssl pkcs12 -info -in xxx.p12 -nodes -nocerts
Enter Import Password:
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
答案2
得分: 0
这个错误是在我们更新了Spring Boot Security至5.4.1及更高版本时出现的。
客户端BC(Bouncy Castle提供者)无法加载X509证书。
无法加载:
PKCS7数据
加密的密钥包:PBES2、PBKDF2、AES-256-CBC、迭代次数10000、PRF hmacWithSHA256
包属性
解决方法是:
使用两个参数调用密钥库实例 "BC"
KeyStore store = KeyStore.getInstance("PKCS12","BC");
---> 然后你会得到旧格式的加密包 ........
英文:
This error occured when we updated SprinBoot Security > 5.4.1
X509 Certificate could not be loaded by client BC(Bouncy Castle Provider).
could not be loaded:
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Bag Attributes
Solution was to:
Call the keystore-Instance with 2 paramter "BC"
KeyStore store = KeyStore.getInstance("PKCS12","BC");
--> then you get the old format shrouded BAG ........
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论