使用 Bouncy Castle 库 c# 解密 pdf.p7m 文件时出现问题
Problem in decrypting a pdf.p7m file with the Bouncy Castle library c#
我在 c# 中有 "translated" java 代码用于解密 pdf 文件。我不明白为什么当我启动一个新的 CmsEnvelopedData 对象时,我得到一个异常:"Attempted to read past the end of the stream"。我还尝试在不安装 NuGet 包的情况下下载 Bouncy Castle 源代码,但我无法弄清楚可能是什么问题。感谢那些愿意提供帮助的人。
代码Java:
public final synchronized byte[] decryptData(byte[] cipherData, String pwd)
throws CSException
{
cipherData = Base64.decode(cipherData);
PrivateKey privKey = null;
privKey = loadKeyFromPKCS12( this.encPrivateKeyId, pwd);
try
{
CMSEnvelopedData envelopedData = new CMSEnvelopedData(cipherData);
RecipientInformationStore recipients = envelopedData.getRecipientInfos();
Collection c = recipients.getRecipients();
Iterator it = c.iterator();
if (it.hasNext())
{
RecipientInformation recipient = (RecipientInformation)it.next();
this.outputBuffer = recipient.getContent(privKey);
}
else{
this.outputBuffer = null;
}
}
return this.outputBuffer;
}
C# 代码:
public byte[] DecryptFile(byte[] file)
{
var fileDecode = Org.BouncyCastle.Utilities.Encoders.Base64.Decode(file);
CmsEnvelopedData envelopedData = new CmsEnvelopedData(fileDecode);
RecipientInformationStore recipients = envelopedData.GetRecipientInfos();
var c = recipients.GetRecipients();
foreach (RecipientInformation recipient in c)
{
var decrypted = recipient.GetContent(RetrievePrivateKey());
return decrypted;
}
return null;
}
读取私钥的C#方法:
private RsaKeyParameters RetrievePrivateKey()
{
var obj = AppConfiguration.GetBasePath();
var path = obj.BasePath + obj.KeystoreFolder;
var keyfolder = new DirectoryInfo(path);
if (!keyfolder.Exists)
{
keyfolder.Create();
}
X509Certificate2 certi = new X509Certificate2(path + obj.KeystoreFile, "Password", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
RSA crypt = certi.GetRSAPrivateKey();
var Akp = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(certi.PrivateKey).Private;
return (RsaKeyParameters)Akp;
}
当我尝试实例化一个新的 CmsEnvelopedData 对象时返回异常:
我也附上示例中使用的加密示例文件:
https://www.dropbox.com/s/gkwovnifpjf1xza/offer.pdf?dl=0
您正在尝试解密部分文件。您显示的文件是单行 base64 字符串。解码后,它会生成一个包含大量 OCTET STRING 值的 ASN.1 编码文件。您遇到的异常是当您尝试读取 ASN.1 编码的二进制值时,但流在可以完全检索之前就结束了。这通常是因为文件尾部丢失,但它当然也可能表明文件已被更改,例如当行尾在二进制文件中转换时,或者如果传输导致(现在不太可能)错误。
文件的尾部经常丢失,因为文件在完全接收之前被复制或移动。例如。如果您使用 FTP 服务器,可能很难判断文件上传何时完成。
我在 c# 中有 "translated" java 代码用于解密 pdf 文件。我不明白为什么当我启动一个新的 CmsEnvelopedData 对象时,我得到一个异常:"Attempted to read past the end of the stream"。我还尝试在不安装 NuGet 包的情况下下载 Bouncy Castle 源代码,但我无法弄清楚可能是什么问题。感谢那些愿意提供帮助的人。
代码Java:
public final synchronized byte[] decryptData(byte[] cipherData, String pwd)
throws CSException
{
cipherData = Base64.decode(cipherData);
PrivateKey privKey = null;
privKey = loadKeyFromPKCS12( this.encPrivateKeyId, pwd);
try
{
CMSEnvelopedData envelopedData = new CMSEnvelopedData(cipherData);
RecipientInformationStore recipients = envelopedData.getRecipientInfos();
Collection c = recipients.getRecipients();
Iterator it = c.iterator();
if (it.hasNext())
{
RecipientInformation recipient = (RecipientInformation)it.next();
this.outputBuffer = recipient.getContent(privKey);
}
else{
this.outputBuffer = null;
}
}
return this.outputBuffer;
}
C# 代码:
public byte[] DecryptFile(byte[] file)
{
var fileDecode = Org.BouncyCastle.Utilities.Encoders.Base64.Decode(file);
CmsEnvelopedData envelopedData = new CmsEnvelopedData(fileDecode);
RecipientInformationStore recipients = envelopedData.GetRecipientInfos();
var c = recipients.GetRecipients();
foreach (RecipientInformation recipient in c)
{
var decrypted = recipient.GetContent(RetrievePrivateKey());
return decrypted;
}
return null;
}
读取私钥的C#方法:
private RsaKeyParameters RetrievePrivateKey()
{
var obj = AppConfiguration.GetBasePath();
var path = obj.BasePath + obj.KeystoreFolder;
var keyfolder = new DirectoryInfo(path);
if (!keyfolder.Exists)
{
keyfolder.Create();
}
X509Certificate2 certi = new X509Certificate2(path + obj.KeystoreFile, "Password", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
RSA crypt = certi.GetRSAPrivateKey();
var Akp = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(certi.PrivateKey).Private;
return (RsaKeyParameters)Akp;
}
当我尝试实例化一个新的 CmsEnvelopedData 对象时返回异常:
我也附上示例中使用的加密示例文件: https://www.dropbox.com/s/gkwovnifpjf1xza/offer.pdf?dl=0
您正在尝试解密部分文件。您显示的文件是单行 base64 字符串。解码后,它会生成一个包含大量 OCTET STRING 值的 ASN.1 编码文件。您遇到的异常是当您尝试读取 ASN.1 编码的二进制值时,但流在可以完全检索之前就结束了。这通常是因为文件尾部丢失,但它当然也可能表明文件已被更改,例如当行尾在二进制文件中转换时,或者如果传输导致(现在不太可能)错误。
文件的尾部经常丢失,因为文件在完全接收之前被复制或移动。例如。如果您使用 FTP 服务器,可能很难判断文件上传何时完成。