首页 > 解决方案 > 从 Crypto Stream 解密 PDF 文件流时未声明字符编码

问题描述

我有以下方法来加密文件并将它们保存到磁盘:

using (FileStream fileStream = new(filePath, FileMode.OpenOrCreate))
        {
            using (Aes aes = Aes.Create())
            {
                byte[] key =
                {
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                    0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
                };
                aes.Key = key;

                byte[] iv = aes.IV;
                fileStream.Write(iv, 0, iv.Length);

                using (CryptoStream cryptoStream = new(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    using (StreamWriter encryptWriter = new(cryptoStream))
                    {
                        await input.File.CopyToAsync(cryptoStream);                            
                    }
                }
            }
        }

以下方法可以从磁盘解密文件并在用户浏览器中打开:

using (FileStream fileStream = new(filePath, FileMode.Open))
        {
            using (Aes aes = Aes.Create())
            {
                byte[] iv = new byte[aes.IV.Length];
                int numBytesToRead = aes.IV.Length;
                int numBytesRead = 0;
                while (numBytesToRead > 0)
                {
                    int n = fileStream.Read(iv, numBytesRead, numBytesToRead);
                    if (n == 0) break;

                    numBytesRead += n;
                    numBytesToRead -= n;
                }

                byte[] key =
                {
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                    0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
                };

                using (CryptoStream cryptoStream = new(fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read))
                {
                    // Desired option - not saving unenrypted to disk
                    var ms = new MemoryStream();
                    await cryptoStream.CopyToAsync(ms);
                    return new FileStreamResult(ms, "application/pdf");

                    // TESTING PURPOSES ONLY - saving unenrypted to disk
                    //var outputStream = new FileStream("C:\\Files\\unencrypted.pdf", FileMode.Create);
                    //await cryptoStream.CopyToAsync(outputStream);                        
                    //return new FileStreamResult(outputStream, "application/pdf");        
                 
                }
            }
        }

我希望用户能够在浏览器中打开文档,而无需将未加密的文件保存回磁盘。

然而,上面的解密结果如下:

未声明纯文本文档的字符编码。如果文档包含 US-ASCII 范围之外的字符,则文档将在某些浏览器配置中呈现乱码。文件的字符编码需要在传输协议中声明或文件需要使用字节顺序标记作为编码签名。

注释掉的代码将未加密的文件保存到磁盘,并且可以从 Windows 资源管理器中打开。但是,在实际应用程序中运行时仍然会导致上述相同的错误。

当然,如果其中的 PDF 具有正确的编码,那么一旦从流的开头删除 IV,未加密的版本也应该如此?

标签: fileasp.net-coresecurityencryptionfilestream

解决方案


推荐阅读