【问题标题】:GZip Magic Number Missing After AES EncryptionAES 加密后 GZip 幻数丢失
【发布时间】:2016-01-03 07:42:46
【问题描述】:

我正在使用 GZip 压缩文件,然后使用 AES 加密。

当我单步执行代码时,我看到幻数 (1f 8b) 存在于中间压缩的未加密数据中,然后文件被加密。当我去解密文件时,中间解密的压缩数据不包含幻数,解压时 GZipStream 失败。

这里是主要代码:

    private static void CompressThenEncrypt(string inputFileName, string outputFileName, ICryptoTransform encryptor)
    {
        using (var inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read))
        {
            using (var outputFileStream = new FileStream(outputFileName, FileMode.Create, FileAccess.Write))
            using (var cryptoStream = new CryptoStream(outputFileStream, encryptor, CryptoStreamMode.Write))
            {
                using (var gZipStream = new GZipStream(cryptoStream, CompressionMode.Compress))
                {
                    inputFileStream.CopyTo(gZipStream);
                }
            }
        }
    }

    private static void DecryptThenDecompress(string inputFileName, string outputFileName, ICryptoTransform decryptor)
    {
        using (var inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read))
        {
            using (var cryptoStream = new CryptoStream(inputFileStream, decryptor, CryptoStreamMode.Read))
            using (var gZipStream = new GZipStream(cryptoStream, CompressionMode.Decompress))
            using (var outputFileStream = new FileStream(outputFileName, FileMode.Create, FileAccess.Write))
            {
                gZipStream.CopyTo(outputFileStream);
            }
        }
    }

源文件为 19000 字节。压缩后变成 603 字节(带有幻数),然后加密后变成 608 字节(由于填充)。解密后它变成 603 字节(没有幻数),我根本无法超越这一点。

这里是调用代码:

        using (var aes = new AesCryptoServiceProvider())
        {
            ICryptoTransform encryptor = aes.CreateEncryptor();
            ICryptoTransform decryptor = aes.CreateDecryptor();

            CompressThenEncrypt(OriginalFileName, CompressThenEncryptFileName, encryptor);

            DecryptThenDecompress(CompressThenEncryptFileName, DecryptThenDecompressFileName, decryptor);
        }

编辑:更多信息

压缩数据(603 字节): 1F-8B-08-00-00-00-00-00-04-00-ED-CA-B1-0D-00-20-08-00-C1-DE-C4-21-51-64-FF- 11-DC-80-84-FE-9A-6F-FE-E2-DC-7C-15-6D-F7-EA-3F-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-5 1-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-D4-44-7D-3F-A6-A4-8A-30-E6-02-00

加密数据(608 字节): C3-02-64-A9-15-15-52-A9-9F-2A-62-EF-89-B2-9A-E0-72-9A-BA-E2-A2-C8-35-BA-3C- CF-D7-07-8B-DC-D4-63-65-AF-A8-62-22-E5-CC-C6-7D-6F-9B-64-57-9F-C0-94-75-E7- 6C-A9-DB-B3-57-29-01-95-F5-B9-E5-3D-FD-AB-EC-E3-AC-AF-EB-A6-C0-81-B3-47-4A- EB-F6-DD-03-DF-92-0A-82-D9-DD-4E-46-DF-55-2E-EB-34-AC-98-1A-7E-A9-25-94-2D- E8-32-4B-F9-2A-61-64-CB-09-9C-D5-8C-A2-0A-C1-22-90-98-93-26-A6-9F-69-F8-EE- 6E-95-96-56-28-71-3B-94-1E-5F-50-DB-15-DF-C6-46-3F-04-57-5E-0B-47-44-BB-13- 9F-14-08-FB-87-E6-97-65-1B-CA-50-52-7F-10-5D-AF-CC-2F-5E-D0-39-A6-C4-70-3B- 90-5F-63-EA-F0-59-46-9E-99-2D-31-34-66-5D-72-E5-85-D5-00-1E-E7-B2-1C-3B-E0- E8-F8-35-BF-90-24-00-DC-47-09-66-92-2F-43-92-48-CB-42-4C-3C-86-CC-67-33-62- A1-1E-76-D1-D6-AD-5F-50-DC-D9-C7-31-F2-33-FE-77-CB-4C-EE-2A-AE-54-63-46-48- B4-FA-6F-0A-E0-1B-F2-F6-C2-D0-E0-24-A1-79-B8-29-FB-04-F3-D5-4E-CC-64-E8-FA- 67-55-7B-E6-CD-FD-D2-13-3D-F0-C4-10-A9-5C-BB-34-66-54-A4-6E-B7-AC-54-7A-21- 5F-C3-01-7B-97-AD-71-C5-2A-E9-39-B1-27-C7-F8-AC-BF-76-EA-D6-C8-05-22-54-4B- 71-73-F2-FD-8E-6E-D7-D2-F 2-F7-83-B3-9F-75-3C-CA-BA-BD-F3-C2-E6-16-37-9E-C1-88-C4-69-F5-95-E8-A5-81- C9-FC-22-73-1D-09-AB-A8-6D-A3-BA-CB-0F-27-4E-C7-8C-7A-6C-9D-9B-9D-1F-45-F2- 7C-B7-7B-F6-DF-24-50-71-A7-BA-F7-F2-8C-AC-19-A3-86-77-4A-EC-5A-06-12-1F-00- AD-5D-EE-E0-61-D0-80-B7-2C-72-2E-77-6A-32-24-0C-64-78-63-37-A9-08-A2-90-9D- 21-5E-E4-5E-E6-1D-66-7D-F5-E1-FC-3C-F1-DE-76-68-D7-1D-46-70-A5-32-31-2B-F5- 02-6A-E4-95-CD-8E-B8-76-8D-6E-0B-98-E9-4A-DD-8D-C3-6F-D8-0C-BE-C7-32-3F-99- 26-94-26-41-80-E4-E6-E7-D3-26-E9-2F-C0-5D-7B-98-24-BD-6E-9B-E8-9D-F6-DF-51- 90-FE-EE-86-DE-9E-31-9F-1C-BA-1A-C4-5B-DD-5A-84-43-02-B9-99-01-6A-95-7C-FF- 86-28-C2-4C-EF-4D-D6-36-BD-08-0F-30-25-E7-FF-D9-BC-DA-A7-87-65-1A-1E-83-55- D2-60-38-EC-51-97-FA-FD-11-70-83-70-66-39-78-47-93-7C-B7-FB-48-96-2F-C6-1E- 6E-7D-29-38-F6-AB-06-45-C5-F7-50-D6-C7-44-5C-AB-96-A0-60-7D-0E-63-4E-B2-EA

解密数据(603 字节): 66-90-D0-0F-8B-67-60-9B-AC-39-FC-45-04-3F-9D-C5-08-00-C1-DE-C4-21-51-64-FF- 11-DC-80-84-FE-9A-6F-FE-E2-DC-7C-15-6D-F7-EA-3F-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-5 1-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14- 45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45- 51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51-14-45-51- 14-45-51-14-45-51-14-45-51-D4-44-7D-3F-A6-A4-8A-30-E6-02-00

如您所见,除了前 16 个字节外,所有数据在压缩格式中都是相同的:

加密前:1F-8B-08-00-00-00-00-00-04-00-ED-CA-B1-0D-00-20

解密后:66-90-D0-0F-8B-67-60-9B-AC-39-FC-45-04-3F-9D-C5

神奇的数字不见了,我不知道为什么。

我正在加密的文件是一个文本文件,其中 abcdefabcdefabcdefabcdefabcdefabcdef 行重复了 5000 次。

【问题讨论】:

  • 那么如果它仍然有 603 个字节,并且缺少幻数,那么新的两个字节是什么?其他 601 字节是否正确?
  • 特定输入文件是否会发生这种情况?我在某个文件上测试了你的代码,它运行良好。
  • @Thilo:除了前 16 个字节之外的所有内容都是相同的。有关这些字节是加密前和解密后的完整信息,请参阅更新的答案。
  • @DarinDimitrov:我正在加密的文件只是一个文本文件,其中abcdefabcdefabcdefabcdefabcdefabcdef 行重复了 5000 次。我在几次尝试中调整了内容,但每次都得到相同的缺失幻数错误,GZipStream 类完全有权抱怨,因为幻数根本不存在。
  • @CodeCaster:感谢您的评论最终引导我找到问题所在!如果我能从这个问题中拯救一个其他开发人员,那我的日子就会过得愉快! :)

标签: c# encryption compression aes gzipstream


【解决方案1】:

只有前 16 个字节(AES 的默认块大小)不正确是另一个问题的签名,即 AesCryptoServiceProvider 解密器对象不能被重用,因为它存储了上次解密的状态信息,这会导致这种奇怪的结果导致随后的解密。

完整的原始调用代码包括解密器对象的致命重用。

完整的原始调用代码:

using (var aes = new AesCryptoServiceProvider())
{
      ICryptoTransform encryptor = aes.CreateEncryptor();
      ICryptoTransform decryptor = aes.CreateDecryptor(); // <-- Decryptor fails on second usage

      // Compress/ Encrypt
      CompressThenEncrypt(OriginalFileName, CompressThenEncryptFileName, encryptor);
      EncryptThenCompress(OriginalFileName, EncryptThenCompressFileName, encryptor);

      // Decrypt/ Decompress
      DecompressThenDecrypt(EncryptThenCompressFileName, DecompressThenDecryptFileName, decryptor);
      DecryptThenDecompress(CompressThenEncryptFileName, DecryptThenDecompressFileName, decryptor);
}

这是我开发的一个个人练习,旨在展示压缩然后加密数据的重要性。我有两个场景“压缩然后加密”和“加密然后压缩”,我还写了代码来执行反向操作。

当我重用 ICryptoTransform 解密器对象时出现问题。尽管CanReuseTransform 属性是true,但它是虚假广告。根据this answer,似乎存在一个错误,即解密后输入缓冲区未正确清除。链接的答案描述了一些解决方法,只需创建一个单独的解密器对象即可。

修改后的工作调用代码:

using (var aes = new AesCryptoServiceProvider())
{
      ICryptoTransform encryptor = aes.CreateEncryptor();
      ICryptoTransform decryptor = aes.CreateDecryptor();
      ICryptoTransform decryptor2 = aes.CreateDecryptor();

      // Compress/ Encrypt
      CompressThenEncrypt(OriginalFileName, CompressThenEncryptFileName, encryptor);
      EncryptThenCompress(OriginalFileName, EncryptThenCompressFileName, encryptor);

      // Decrypt/ Decompress
      DecompressThenDecrypt(EncryptThenCompressFileName, DecompressThenDecryptFileName, decryptor);
      DecryptThenDecompress(CompressThenEncryptFileName, DecryptThenDecompressFileName, decryptor2);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 2014-07-01
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 2011-03-18
    相关资源
    最近更新 更多