使用 Bouncy Castle 解密 PEM 私钥 (RSA)
Decrypt PEM private (RSA) key with Bouncy Castle
目标:从加密的 PEM 文件中提取 RSA 私钥。私钥将用于以编程方式签署证书。
环境:Java 8 和充气城堡 1.52
使用 Bouncy Castle PEMParser(导致 PKCSException)
//Register BC as a crypto provider
Security.addProvider(new BouncyCastleProvider());
//Get file handle
String caPrivateKeyFname = "cakey.pem";
FileInputStream fis = null;
try {
fis = new FileInputStream(caPrivateKeyFname);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Load and parse PEM object
PEMParser pemRd = new PEMParser(new InputStreamReader(fis));
Object objectInPemFile = pemRd.readObject();
//I do not know why BC loads the file as a PKCS8 object. OpenSSL does not recognize it as such.
PKCS8EncryptedPrivateKeyInfo keyInfo = (PKCS8EncryptedPrivateKeyInfo) objectInPemFile;
//Decrypt the private key
String pwd = "secret";
InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(pwd.toCharArray());
//Next statement raises an exception.
PrivateKeyInfo privateKeyInfo = keyInfo.decryptPrivateKeyInfo(pkcs8Prov);
Exception in thread "main" org.bouncycastle.pkcs.PKCSException: unable to read encrypted data: 1.2.840.113549.1.5.13 not available: Illegal key size
at org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(Unknown Source)
at org.codice.ddf.certificate.SignedCertificate.main(SignedCertificate.java:67)
Caused by: org.bouncycastle.operator.OperatorCreationException: 1.2.840.113549.1.5.13 not available: Illegal key size
at org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder.get(Unknown Source)
... 2 more
Caused by: java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1060)
at javax.crypto.Cipher.implInit(Cipher.java:809)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1539)
at javax.crypto.Cipher.init(Cipher.java:1470)
... 3 more
* 更新 *
openssl asn1parse -in cakey.pem
PBES2
PBKDF2
des-ede3-cbc
如果我没理解错的话,DES密钥长度是64位,所以3DES是192位密钥。
但是,Java 策略将 DES 密钥的长度限制为 56 位,因此 3DES 的最大密钥长度为 168 位。
关闭管辖政策文件对我来说不是一个选择。我认为有一种方法可以用 Bouncy Castle 解密 PKCS8 加密的私钥,但该解决方案比将提供者设置为 BC 更复杂。
谁能给我举个例子或提供一些参考代码?
(感谢 dave_thompson_085 的帮助)。
是的,以“-----BEGIN ENCRYPTED PRIVATE KEY-----”行开头的文件是 PEM 格式的 PKCS#8 加密私钥。我不知道为什么你的评论说 "OpenSSL does not recognize it"; openssl rsa
成功读取它的事实证明 OpenSSL 确实识别它。
BC PKCSException
只是一个包装器;你的实际问题是java.security.InvalidKeyException: Illegal key size
。如果您尝试在 JRE 中使用优于 128 位的对称加密或(如此处)解密,而该 JRE 具有默认的 shipped-by-Sun-now-Oracle 加密策略,该策略仅限于 128 位对称。我敢打赌 openssl asn1parse <cakey.pem
显示使用 PBES2
使用 PBKD2
(带有一些参数)和 aes-192-cbc
或 aes-256-cbc
.[=19 加密的文件=]
从 [=18= 的 "Additional Resources" 部分下载 JDK/JRE 8 的“... (JCE) Unlimited Strength Jurisdiction Policy Files” ] 然后解压,把两个*policy.jar文件放到你用的JRE的JREHOME/lib/security目录下。 (假设你没有受到美国的制裁,因为你在朝鲜、伊朗或叙利亚政府等。)
目标:从加密的 PEM 文件中提取 RSA 私钥。私钥将用于以编程方式签署证书。
环境:Java 8 和充气城堡 1.52
使用 Bouncy Castle PEMParser(导致 PKCSException)
//Register BC as a crypto provider
Security.addProvider(new BouncyCastleProvider());
//Get file handle
String caPrivateKeyFname = "cakey.pem";
FileInputStream fis = null;
try {
fis = new FileInputStream(caPrivateKeyFname);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Load and parse PEM object
PEMParser pemRd = new PEMParser(new InputStreamReader(fis));
Object objectInPemFile = pemRd.readObject();
//I do not know why BC loads the file as a PKCS8 object. OpenSSL does not recognize it as such.
PKCS8EncryptedPrivateKeyInfo keyInfo = (PKCS8EncryptedPrivateKeyInfo) objectInPemFile;
//Decrypt the private key
String pwd = "secret";
InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(pwd.toCharArray());
//Next statement raises an exception.
PrivateKeyInfo privateKeyInfo = keyInfo.decryptPrivateKeyInfo(pkcs8Prov);
Exception in thread "main" org.bouncycastle.pkcs.PKCSException: unable to read encrypted data: 1.2.840.113549.1.5.13 not available: Illegal key size
at org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(Unknown Source)
at org.codice.ddf.certificate.SignedCertificate.main(SignedCertificate.java:67)
Caused by: org.bouncycastle.operator.OperatorCreationException: 1.2.840.113549.1.5.13 not available: Illegal key size
at org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder.get(Unknown Source)
... 2 more
Caused by: java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1060)
at javax.crypto.Cipher.implInit(Cipher.java:809)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1539)
at javax.crypto.Cipher.init(Cipher.java:1470)
... 3 more
* 更新 *
openssl asn1parse -in cakey.pem
PBES2
PBKDF2
des-ede3-cbc
如果我没理解错的话,DES密钥长度是64位,所以3DES是192位密钥。 但是,Java 策略将 DES 密钥的长度限制为 56 位,因此 3DES 的最大密钥长度为 168 位。
关闭管辖政策文件对我来说不是一个选择。我认为有一种方法可以用 Bouncy Castle 解密 PKCS8 加密的私钥,但该解决方案比将提供者设置为 BC 更复杂。
谁能给我举个例子或提供一些参考代码?
(感谢 dave_thompson_085 的帮助)。
是的,以“-----BEGIN ENCRYPTED PRIVATE KEY-----”行开头的文件是 PEM 格式的 PKCS#8 加密私钥。我不知道为什么你的评论说 "OpenSSL does not recognize it"; openssl rsa
成功读取它的事实证明 OpenSSL 确实识别它。
BC PKCSException
只是一个包装器;你的实际问题是java.security.InvalidKeyException: Illegal key size
。如果您尝试在 JRE 中使用优于 128 位的对称加密或(如此处)解密,而该 JRE 具有默认的 shipped-by-Sun-now-Oracle 加密策略,该策略仅限于 128 位对称。我敢打赌 openssl asn1parse <cakey.pem
显示使用 PBES2
使用 PBKD2
(带有一些参数)和 aes-192-cbc
或 aes-256-cbc
.[=19 加密的文件=]
从 [=18= 的 "Additional Resources" 部分下载 JDK/JRE 8 的“... (JCE) Unlimited Strength Jurisdiction Policy Files” ] 然后解压,把两个*policy.jar文件放到你用的JRE的JREHOME/lib/security目录下。 (假设你没有受到美国的制裁,因为你在朝鲜、伊朗或叙利亚政府等。)