C#中使用Bouncy Castle解密3DES加密PDF的问题求助
解决3DES加密PDF解密时
Decode方法抛出的CryptographicException问题 核心问题分析
你遇到的错误大概率是因为加密用了Bouncy Castle的CMS实现,解密却混用了.NET原生的EnvelopedCms类,两者对PKCS#7 EnvelopedData结构的处理存在兼容性差异(比如扩展属性、编码细节),导致.NET无法解析Bouncy Castle生成的加密数据。
解决步骤
1. 统一用Bouncy Castle完成解密
最可靠的方式是和加密环节保持一致,全程使用Bouncy Castle的API处理解密,避免跨库兼容性问题。以下是完整的解密代码示例:
using Org.BouncyCastle.Cms; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; using Org.BouncyCastle.X509; using System.IO; using System.Linq; // 解密方法:输入加密后的CMS数据、私钥、对应收件人证书 public static byte[] Decrypt3DESPdf(byte[] encryptedCmsData, AsymmetricKeyParameter privateKey, X509Certificate recipientCert) { // 解析加密的CMS数据 CmsEnvelopedData envelopedData = new CmsEnvelopedData(encryptedCmsData); // 获取收件人信息存储,匹配当前证书对应的收件人条目 RecipientInformationStore recipientStore = envelopedData.GetRecipientInfos(); RecipientInformation recipientInfo = recipientStore.GetFirstRecipient(recipientCert); // 用私钥解密对称密钥,再解密PDF内容 return recipientInfo.GetContent(privateKey); } // 加载PFX格式的私钥(对应加密时使用的证书) private static AsymmetricKeyParameter LoadPrivateKeyFromPfx(string pfxFilePath, string pfxPassword) { using var fs = new FileStream(pfxFilePath, FileMode.Open, FileAccess.Read); Pkcs12Store pkcsStore = new Pkcs12Store(fs, pfxPassword.ToCharArray()); // 获取第一个密钥条目(如果有多个别名,需根据实际情况调整) string keyAlias = pkcsStore.Aliases.Cast<string>() .First(alias => pkcsStore.IsKeyEntry(alias)); AsymmetricKeyEntry keyEntry = pkcsStore.GetKey(keyAlias); return keyEntry.Key; }
2. 验证加密代码的规范性
确保加密环节生成的是标准PKCS#7 EnvelopedData结构,检查以下几点:
- 加密时是否指定了正确的3DES算法标识:使用
CmsEnvelopedDataGenerator.DesEde3Cbc而非自定义OID - 是否正确添加收件人证书:调用
generator.AddKeyTransRecipient(encryptCert) - 生成的加密数据是否完整,没有被截断、编码转换错误(比如误将二进制转成字符串再转回)
3. 若需使用.NET原生EnvelopedCms的兼容处理
如果必须用.NET原生类解密,需在加密时强制Bouncy Castle生成符合.NET预期的CMS结构:
- 禁用Bouncy Castle的扩展属性生成,确保只包含标准PKCS#7字段
- 加密时指定与.NET兼容的编码格式(比如DER编码)
但这种方式容易出现未知兼容问题,优先推荐同库处理方案。
内容的提问来源于stack exchange,提问作者Valerio M.
相关产品推荐
相关产品推荐

