简体   繁体   English

解密AES密文

[英]Decrypting AES cipher text

Consider the following test: 考虑以下测试:

    [Test]
    public void TestAes256EcbPkcs7Stream()
    {
        // 504 bytes of plain text
        const string inputString = new string('z', 504);
        var inputBytes = Encoding.UTF8.GetBytes(inputString);
        byte[] key = {
            0, 0, 0, 0, 0, 0, 0, 0,
            1, 0, 0, 0, 0, 0, 0, 0,
            2, 0, 0, 0, 0, 0, 0, 0,
            3, 0, 0, 0, 0, 0, 0, 0
        };
        var rij = new RijndaelManaged
        {
            BlockSize = 256, // 256 bits == 32 bytes
            Key = key,
            IV = key, // just for test
            Mode = CipherMode.ECB,
            Padding = PaddingMode.PKCS7
        };
        var enc = rij.CreateEncryptor();
        var encBytes = enc.TransformFinalBlock(inputBytes, 0, inputBytes.Length);
        Assert.AreEqual(512, encBytes.Length);
        var dec = rij.CreateDecryptor();
        byte[] decBytes = new byte[inputBytes.Length];
        int decPos = 0;
        using (var cipherMs = new MemoryStream(encBytes))
        {
            var buf = new byte[32];
            // process all blocks except the last one
            while (cipherMs.Read(buf, 0, buf.Length)==buf.Length &&
                cipherMs.Length!=cipherMs.Position)
            {
                for (int w = 0; w!=buf.Length;)
                {
                    w += dec.TransformBlock(buf, 0, buf.Length, decBytes, decPos);
                    decPos += w;
                }
            }
            // ensure that we read all blocks
            Assert.IsTrue(cipherMs.Length==cipherMs.Position);
            // process the last block
            var tailBytes = dec.TransformFinalBlock(buf, 0, buf.Length);
            // here decPos==480, that means 480 bytes were written to decBytes
            // and 504-480 = 24 bytes come from TransformFinalBlock
            Assert.AreEqual(24, tailBytes.Length); // <- fail, because the actual length is 56
            Buffer.BlockCopy(tailBytes, 0, decBytes, decPos, tailBytes.Length);
        }
        Assert.AreEqual(inputBytes, decBytes);
    }

For some reason I got 56-byte final block instead of 24-byte. 由于某种原因,我得到了56字节的最终块,而不是24字节。 I suppose, TransformBlock / TransformFinalBlock should be used in some other way, but unfortunately, MSDN docs don't explain much about these methods. 我想应该以其他方式使用TransformBlock / TransformFinalBlock ,但是不幸的是,MSDN文档对这些方法的解释不多。 Any thoughts? 有什么想法吗?

Ok, here's the thing: When TransformBlock is called first time, it copies the last block of the input buffer to the so called depad buffer and then transforms and writes remaining blocks to the output buffer. 好的,事情是这样的:第一次调用TransformBlock时,它将输入缓冲区的最后一个块复制到所谓的depad缓冲区 ,然后进行转换并将剩余的块写入输出缓冲区。 During next calls it transforms data from depad buffer, writes it to the output buffer, copies the last block of the input buffer to the depad buffer again, and writes transformed remaining blocks to the output, just as the first time. 在下一次调用期间,它将数据转换为来自depad缓冲区的数据,将其写入输出缓冲区,将输入缓冲区的最后一个块再次复制到depad缓冲区,然后将转换后的剩余块写入到输出中,就像第一次一样。

TL;DR: TransformBlock caches the last block of input data so when TransformFinalBlock is called, it can grab the last block and remove padding. TL; DR: TransformBlock缓存输入数据的最后一块,因此在调用TransformFinalBlock时,它可以抓住最后一块并删除填充。 Without caching, the last block may be handled by TransformBlock . 如果不进行缓存,则最后一个块可以由TransformBlock处理。 In that case, padding wouldn't be removed. 在这种情况下,不会删除填充。

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

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