【问题标题】:Unexpected encrypted string with AES 256 bit ECB in C#C# 中带有 AES 256 位 ECB 的意外加密字符串
【发布时间】:2019-06-04 13:17:33
【问题描述】:

我正在尝试使用 AES 256 ECB 对字符串进行编码,并使用 .Net 的 System.Security.Cryptography 库填充零,但结果不是我所期望的。

我正在使用与my reciver's code 匹配的this test case 进行测试。

我的代码如下所示:

public static class Util
{
    public static byte[] StringToByteArray(string hex)
    {
        return Enumerable.Range(0, hex.Length)
                             .Where(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
    }

    private static readonly byte[] KEY = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
    private static readonly byte[] IV = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    public static byte[] Encrypt(string original)
    {
        byte[] encrypted;
        using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
        {
            aesAlg.Padding = PaddingMode.Zeros;
            aesAlg.Mode = CipherMode.ECB;
            aesAlg.KeySize = 256;

            // Create the streams used for encryption.
            using (ICryptoTransform encryptor = aesAlg.CreateEncryptor(KEY, IV))
            using (MemoryStream msEncrypt = new MemoryStream())
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    //Write all data to the stream.
                    var bytes = Encoding.ASCII.GetBytes(original);
                    swEncrypt.Write(bytes);
                }
                encrypted = msEncrypt.ToArray();
            }
        }
        return encrypted;
    }
}

那么,这是我的测试用例失败了,十六进制的结果数组是 05212CB5430653FA4BD2253D20353903 而不是 9798D10A63E4E167122C4C07AF49C3A9。

public void TesEncrypt()
{
    var array = Util.Encrypt("text to encrypt");
    var expected = Util.StringToByteArray("9798D10A63E4E167122C4C07AF49C3A9");
    CollectionAssert.AreEqual(expected, array);
}

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    这个:

    //Write all data to the stream.
    var bytes = Encoding.ASCII.GetBytes(original);
    swEncrypt.Write(bytes);
    

    应该是

    //Write all data to the stream.
    swEncrypt.Write(original);
    

    StreamWriter 已经负责将您的字符串序列化为字节数组。

    Here's a working fiddle.(我没有可用的 Assert.AreEqual,但前两个字节与您的预期输出匹配。哦,顺便说一下,Assert.AreEqual is wrong here,您应该改用CollectionAssert.AreEqual。)

    我注意到您的原始代码返回了与输入无关的相同输出,从而发现了这个错误。发生的情况是调用了TextWriter.Write(object) overload,它在您的字节数组上调用ToString(产生字符串"System.Byte[]")并加密该字符串(而不是您的输入字符串)。

    【讨论】:

    • 太棒了!顺便说一句,由于参考比较而不是数据比较,我正在测试我的代码。
    猜你喜欢
    • 2018-07-08
    • 2012-11-22
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 2021-01-19
    • 2016-05-26
    相关资源
    最近更新 更多