Шифрование файлов с использованием ключей X509 - PullRequest
0 голосов
/ 02 апреля 2020

Я достиг конца моей веревки с этой проблемой. Предпосылки: Реализация возможности зашифровать все файлы с помощью Steam из NetCore API

Реализация проходит все тесты, которые я могу выполнить, как в NetFULL, так и в NetCore. Я выбросил сотни различных типов файлов из простого текста, Word, Excel, PDF, и каждый файл шифрует и дешифрует. Однако при вызове из API из внешнего интерфейса Angular происходит сбой процесса.

Расследование обнаружило, что во время шифрования файл заканчивается повреждением, как при замене «зашифрованного» файла из загрузить с другим файлом, зашифрованным из модульных тестов, расшифровать и загрузить работу безупречно.

Я использую надувной замок для выполнения реальной работы. Вот методы, которые я использую для шифрования и дешифрования. Любое руководство будет полезно.

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

1 Ответ

0 голосов
/ 06 апреля 2020

проблема заключалась в том, что 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;
            }
        }
...