2

假设使用 256 密钥/IV 使用 AES 对少量数据进行加密。加密的数据可能是已知的。例如:

abcdefghijklmno|axXXyyYY343433553353afsafaadfafdfsafsf|2013-01-01T00:00:00

前两部分(如果你打破管道字符上的数据)很少改变。最后一部分,日期/时间确实会改变,但不会经常改变。我注意到更改日期而不是消息的第一部分会导致密码文本始终以相同的开头,大概是因为纯文本的开头是相同的。

这会让我对加密算法进行任何类型的攻击吗?我会通过在纯文本的开头添加盐值来获得什么吗?

我正在使用AesManaged该类来生成 IV / Key 并加密 / 解密纯文本,如果这有所作为的话。

4

3 回答 3

4

为了解决这个问题,通常为每个密文随机生成IV,并在加密数据前添加未加密的IV。这样,每个加密数据都与其他数据不同。

在代码中应该是

string str = "abcdefghijklmno|axXXyyYY343433553353afsafaadfafdfsafsf|2013-01-01T00:00:00";
byte[] data = Encoding.UTF8.GetBytes(str);
byte[] key = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; // Your random key, I hope more random!

byte[] encrypted;

// Encrypt

using (var am = new AesManaged())
using (var rng = new RNGCryptoServiceProvider())
{
    am.Key = key;

    var iv = new byte[am.BlockSize / 8];
    rng.GetBytes(iv);
    am.IV = iv;

    using (var encryptor = am.CreateEncryptor())
    using (var ms = new MemoryStream())
    {
        ms.Write(iv, 0, iv.Length);

        using (var encStream = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
        {
            encStream.Write(data, 0, data.Length);
        }

        encrypted = ms.ToArray();
    }
}

// Decrypt

string str2;

using (var am = new AesManaged())
using (var ms = new MemoryStream(encrypted))
{
    am.Key = key;

    var iv = new byte[am.BlockSize / 8];
    ms.Read(iv, 0, iv.Length);
    am.IV = iv;

    using (var decryptor = am.CreateDecryptor())
    using (var decStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
    using (var ms2 = new MemoryStream())
    {
        decStream.CopyTo(ms2);

        str2 = Encoding.UTF8.GetString(ms2.GetBuffer(), 0, (int)ms2.Length);
    }
}

请注意,通常 IV 重用会导致加密的弱点。参见例如wiki

对于 CBC 和 CFB,重用 IV 会泄露一些关于第一个明文块以及两条消息共享的任何公共前缀的信息。对于 OFB 和 CTR,重用 IV 会完全破坏安全性。 [6]

于 2013-09-16T19:14:28.617 回答
2

这是IV的主要目的之一。您应该为您发送的每条消息生成一个随机 IV(如果您已经这样做了,那么您的代码中一定有问题)。

于 2013-09-16T19:14:23.273 回答
-3

AES256 应该混合 256 位(32 字节)块中的数据。由于您的前导文本很长(>32 字节)很少更改,因此使用加密方法的性能会很差。您可以解决此问题,但只要明文字符串在前 32 个字节内更改,就可以使用频繁更改的内容开头。您可以通过创建一些随机种子和实际有用的数据来做到这一点。

播种的目的是使“已知”字符串在加密后不会生成可识别的模式。这是您将遇到的确切问题,因此您需要播种数据或至少在明文开头附近使用易失性数据。

编辑:我看到我有负面影响,想知道为什么。首先,通过性能我打算指的是加密的质量,而不是执行时间。当我指的是盐时,我不小心说了种子。一个小错误,但我明白为什么是负面的。我留下我的答案是因为它是唯一一次解释(或试图解释)频繁变化的盐(或至少是某些东西)确实需要与馈送到 AES-256 的 32 字节明文块一起出现。如果您的加密数据受到字典攻击(例如密码)的影响,通常需要加盐,这对于 OP 来说似乎不太可能,但您的加密数据永远不应该是“可预测的”,这就是为什么 OP 应该在前 32 个数据中加盐字节。

于 2013-09-16T19:08:01.280 回答