【问题标题】:File Encryption using X509 Keys使用 X509 密钥的文件加密
【发布时间】:2020-07-14 20:48:36
【问题描述】:

这个问题我已经走到了尽头。 背景:实现通过来自 NetCore API 的 Steam 加密所有文件的能力

该实现通过了我可以在 NetFULL 和 NetCore 下进行的所有测试。我从纯文本、Word、Excel、PDF 中抛出了数百种不同的文件类型,每个文件都加密和解密。但是,当从 Angular 前端的 API 调用时,流程就会中断。

调查发现,在加密过程中,文件最终被损坏,因为当我将上传中的“加密”文件替换为单元测试中加密的另一个文件时,解密和下载工作完美无缺。

我正在使用充气城堡来执行实际工作。这是我用来加密和解密的方法。任何指导都会有所帮助。

        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);
        }
    }

【问题讨论】:

  • 与往常一样,一些说明问题的测试输入和输出将有很长的路要走。

标签: c# .net encryption .net-core bouncycastle


【解决方案1】:

问题是 void IsFileEncrypted() 在检查后将流位置设置回 0,但是上传文件在 Content-Disposition 中的位置不为 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;
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2014-10-24
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多