C# 使用X509密钥进行文件加密
我对这个问题已经束手无策了。 背景:实现通过NetCore API中的数据流对所有文件进行加密的功能 该实现通过了我在NetFULL和NetCore下对其进行的所有测试。我抛出了数百种不同的文件类型,包括纯文本、Word、Excel、PDF,每个文件都进行加密和解密。然而,当从一个角度前端从API调用时,流程就会崩溃 调查发现,正是在加密过程中,文件最终被破坏,因为当我用另一个单元测试加密的文件替换上传的“加密”文件时,解密和下载工作完美无瑕 我用bouncy castle来完成真正的工作。下面是我用来加密和解密的方法。任何指导都会有帮助C# 使用X509密钥进行文件加密,c#,.net,encryption,.net-core,bouncycastle,C#,.net,Encryption,.net Core,Bouncycastle,我对这个问题已经束手无策了。 背景:实现通过NetCore API中的数据流对所有文件进行加密的功能 该实现通过了我在NetFULL和NetCore下对其进行的所有测试。我抛出了数百种不同的文件类型,包括纯文本、Word、Excel、PDF,每个文件都进行加密和解密。然而,当从一个角度前端从API调用时,流程就会崩溃 调查发现,正是在加密过程中,文件最终被破坏,因为当我用另一个单元测试加密的文件替换上传的“加密”文件时,解密和下载工作完美无瑕 我用bouncy castle来完成真正的工作。下面
public virtual void EncryptFileStream(Stream stream, X509Certificate2 encryptingCertificate, Stream encryptedStream)
{
if (!encryptingCertificate.HasPrivateKey || encryptingCertificate.PrivateKey == null)
{
throw new ArgumentException(nameof(encryptingCertificate) + " Does not have a private key");
}
if (!IsFileEncrypted(stream))
{
var dataGenerator = new CmsEnvelopedDataStreamGenerator();
dataGenerator.AddKeyTransRecipient(DotNetUtilities.FromX509Certificate(encryptingCertificate));
var cryptoStream = dataGenerator.Open(encryptedStream, CmsEnvelopedGenerator.Aes128Cbc);
using (var fs = new BinaryWriter(cryptoStream))
{
stream.CopyTo(fs.BaseStream);
}
cryptoStream.Close();
}
}
public virtual void DecryptFileStream(Stream encryptedStream, X509Certificate2 encryptingCertificate, Stream decryptedStream)
{
if (!encryptingCertificate.HasPrivateKey || encryptingCertificate.PrivateKey == null)
{
throw new ArgumentException(nameof(encryptingCertificate) + " Does not have a private key");
}
if (IsFileEncrypted(encryptedStream))
{
CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(encryptedStream);
RecipientInformationStore recipients = ep.GetRecipientInfos();
var cert = DotNetUtilities.FromX509Certificate(encryptingCertificate);
var keyPair = DotNetUtilities.GetKeyPair(encryptingCertificate.PrivateKey);
RecipientID recSel = new RecipientID
{
Issuer = PrincipalUtilities.GetIssuerX509Principal(cert), SerialNumber = cert.SerialNumber
};
RecipientInformation recipient = recipients.GetFirstRecipient(recSel);
CmsTypedStream recData = recipient.GetContentStream(keyPair.Private);
recData.ContentStream.CopyTo(decryptedStream);
}
}
问题是void IsFileEncrypted()在检查后将流位置设置回0,但是上载文件在内容处置中的位置不是0,因此目标文件格式不正确。修复方法是固定蒸汽的起始位置,而不是将蒸汽重置回其原始位置
public virtual bool IsFileEncrypted(Stream stream)
{
var currentStreamPosition = stream.Position;
try
{
CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(stream);
RecipientInformationStore recipients = ep.GetRecipientInfos();
return recipients != null;
}
catch
{
return false;
}
finally
{
stream.Position = currentStreamPosition;
}
}
和往常一样,一些说明问题的测试输入和输出将大有帮助。