c# - 一个新的随机初始化向量在加密过程中总是产生相同的密文

标签 c# encryption aes initialization-vector

我在这里阅读了一些关于正确使用初始化向量的主题,并且正在重构一些现有代码以对每个项目使用随机 IV。

我有一个方法需要一个数据 block 和一个 key ,并且应该使用提供的 key 和一个随机 IV 来加密这个 block 。

public static byte[] AesEncrypt(byte[] data, byte[] key)
{
    byte[] output = new byte[0];

    Console.WriteLine("Data: {0}", Encoding.ASCII.GetString(data));
    Console.WriteLine("Key: {0}", BitConverter.ToString(key));

    using (AesCryptoServiceProvider acp = new AesCryptoServiceProvider())
    {
        acp.GenerateIV();
        byte[] vector = acp.IV;
        using (ICryptoTransform trans = acp.CreateEncryptor(key, vector))
        {

            Console.WriteLine("Vector: {0}", BitConverter.ToString(vector));
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, trans, CryptoStreamMode.Write))
                using(BinaryWriter bw = new BinaryWriter(cs))
                {
                    bw.Write(vector);
                    bw.Write(data);
                    cs.FlushFinalBlock();
                    output = ms.ToArray();
                }
            }
        }
    }
    Console.WriteLine("Output: {0}", BitConverter.ToString(output));
    return output;
}

目的是防止为相同的数据输入和 key 生成相同的密码。不幸的是,虽然控制台输出显示每次生成不同的 IV,但使用相同数据和 key 多次调用该方法会导致相同的密码。

Data: 4761739001010010
Key: 7C-26-D9-6B-A1-FC-9E-67-9A-A2-7D-5F-52-5C-09-54-FE-DD-A5-C6-90-DD-0F-B3-CC-E2-7E-0E-4F-2D-2E-97
Vector: ED-02-6E-C6-B3-7A-74-66-4B-E5-47-23-16-D6-87-3B
Output: CB-F7-93-16-64-24-E2-F0-81-00-99-DA-97-F1-46-43-7D-F7-C4-AC-2E-C8-D4-D9-F1-7C-67-6E-F3-14-F0-4F-C7-1B-02-AE-41-4C-6B-B9-80-3A-64-4B-14-10-60-1B

Data: 4761739001010010
Key: 7C-26-D9-6B-A1-FC-9E-67-9A-A2-7D-5F-52-5C-09-54-FE-DD-A5-C6-90-DD-0F-B3-CC-E2-7E-0E-4F-2D-2E-97
Vector: 3E-3B-32-FB-82-03-03-9F-54-96-67-AA-29-5E-09-C4
Output: CB-F7-93-16-64-24-E2-F0-81-00-99-DA-97-F1-46-43-7D-F7-C4-AC-2E-C8-D4-D9-F1-7C-67-6E-F3-14-F0-4F-C7-1B-02-AE-41-4C-6B-B9-80-3A-64-4B-14-10-60-1B

知道哪里出了问题吗?

最佳答案

你看到的其实是正确的行为......

问题是您写入加密流的第一件事是向量。

如果您查看此链接:https://security.stackexchange.com/questions/44442/using-aescryptoserviceprovider-in-c-should-using-an-incorrect-iv-mangle-just-t

它解释了 CBC 模式下的第一个操作是将您提供的数据(在您的情况下为向量)与提供的向量进行异或。 所以基本上,无论您提供什么向量,第一个要加密的数据(在 XOR 操作之后)将由 0 组成 参见:http://en.wikipedia.org/wiki/Exclusive_or

下一个使用的向量将是第一个加密的数据 block ,因此 0 使用您的 key 加密,这就是为什么无论您提供什么向量,您都看不到任何差异。

如果你只是评论这一行:

bw.Write(vector);

您会看到预期的行为。

关于c# - 一个新的随机初始化向量在加密过程中总是产生相同的密文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29850048/

相关文章:

c# - 异常处理中函数参数的一般记录

c# - 将 oracle db 配置为 Quartz.net 调度程序时出错

security - 创建一个开发服务器,就像让我们加密一样

c++ - AES128 加密 libgcrypt 输出垃圾

c++ - 无法使用 Intel AES-NI 示例库以 32 字节 block 大小进行加密/解密

c# - 通过不同环境的代码检查 32 位?

c# - 分组查询时无法使用 ExecuteReader() 检索数据

encryption - AES128 CBC 可以使用 0 填充吗?

encryption - 哪些可打印的 ASCII 字符通常会出现在英文文本中?

java - AES加密抛出 "Illegal Key Size error"