简体   繁体   English

使用 X509 密钥的文件加密

[英]File Encryption using X509 Keys

I've reached the end of my rope with this issue.对于这个问题,我已经走到了尽头。 Background: Implementing the ability to encrypted all file via steams from a NetCore API背景:实现通过来自 NetCore API 的流加密所有文件的能力

The implementation passes every test I can throw at it under both NetFULL and NetCore.该实现通过了我可以在 NetFULL 和 NetCore 下对其进行的所有测试。 I've thrown hundreds of different file types from plain text, Word, Excel, PDF and every file encrypts and decrypts.我从纯文本、Word、Excel、PDF 中抛出了数百种不同的文件类型,每个文件都会加密和解密。 However when called from the API from an Angular front end is where the process breaks down.但是,当从 Angular 前端从 API 调用时,过程就会中断。

Investigation has found that it's during encryption that the file ends up being corrupted as when I replace the "encrypted" file from upload with another file encrypted from unit tests, the decrypt and download work flawlessly.调查发现,在加密过程中,文件最终被损坏,因为当我用另一个从单元测试加密的文件替换上传的“加密”文件时,解密和下载工作完美无缺。

I'm using bouncy castle to perform the real work.我正在使用充气城堡来执行实际工作。 Here is the methods I'm using to encrypt and decrypt.这是我用来加密和解密的方法。 Any guidance would be helpful.任何指导都会有所帮助。

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

the issue was that void IsFileEncrypted() was setting the stream position back to 0 after checking, however the position of the uploaded file in a Content-Disposition is not at 0, hence malforming the target file.问题是 void IsFileEncrypted() 在检查后将流位置设置回 0,但是上传文件在 Content-Disposition 中的位置不是 0,因此导致目标文件格式错误。 The fix was to fix track the starting position of the steam than resetting the stream back to it's original position.解决方法是修复跟踪蒸汽的起始位置,而不是将蒸汽重置回其原始位置。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM