求助:JceKeyTransEnvelopedRecipient(PublicKey)构造函数未定义问题
解决JceKeyTransEnvelopedRecipient构造函数未定义及解密参数错误问题
你的核心问题出在JceKeyTransEnvelopedRecipient的构造参数类型错误:这个类的构造函数需要的是收件人的私钥,而你传入的是公钥——解密操作必须用私钥,公钥只用于加密环节。另外注意,BouncyCastle不同版本API存在差异,要确保你使用的是兼容版本(比如1.77+)。
修正步骤及代码示例
- 加载私钥:私钥通常和证书一起存在PKCS#12格式的密钥库(.p12/.pfx)中,需从密钥库读取
- 用私钥实例化JceKeyTransEnvelopedRecipient
- 用try-with-resources自动关闭流,避免资源泄漏
修正后的完整代码:
import org.bouncycastle.cms.CMSEnvelopedDataParser; import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; public class BouncyCastleDecrypt { public static void main(String[] args) { try { // 加载证书(可选,用于验证收件人信息,也可从密钥库直接获取) CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); try (FileInputStream certFileInputStream = new FileInputStream("xxxx.crt")) { X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certFileInputStream); } // 从PKCS#12密钥库加载私钥 KeyStore keyStore = KeyStore.getInstance("PKCS12"); char[] keyStorePassword = "你的密钥库密码".toCharArray(); // 替换为实际密码 try (FileInputStream keyStoreInputStream = new FileInputStream("xxxx.p12")) { keyStore.load(keyStoreInputStream, keyStorePassword); } PrivateKey privateKey = (PrivateKey) keyStore.getKey("密钥别名", keyStorePassword); // 替换为实际密钥别名 // 解析加密文件并解密 try (FileInputStream encryptedFileInputStream = new FileInputStream("xxxx.enc")) { CMSEnvelopedDataParser parser = new CMSEnvelopedDataParser(encryptedFileInputStream); RecipientInformationStore recipientInfos = parser.getRecipientInfos(); RecipientInformation recipientInfo = recipientInfos.getRecipients().iterator().next(); JceKeyTransEnvelopedRecipient recipient = new JceKeyTransEnvelopedRecipient(privateKey); byte[] decryptedData = recipientInfo.getContent(recipient); // 写入解密后文件 try (FileOutputStream decryptedOutputStream = new FileOutputStream("final_file.pdf")) { decryptedOutputStream.write(decryptedData); } System.out.println("解密完成!"); } } catch (Exception e) { e.printStackTrace(); } } }
额外注意事项
- 如果私钥是PEM格式,需要用BouncyCastle的
PEMParser读取,调整私钥加载逻辑 - 确保项目引入正确的BouncyCastle依赖,Maven示例:
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> <version>1.77</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk18on</artifactId> <version>1.77</version> </dependency>
内容的提问来源于stack exchange,提问作者Pedro Marques
相关产品推荐
相关产品推荐

