将salt添加到要加密的数据中?

时间:2013-09-16 18:51:27

标签: c# encryption aes

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

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

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

这是否会让我受到针对加密算法的任何攻击?我可以通过在纯文本的开头添加一个salt值来获得任何东西吗?

我正在使用AesManaged类生成IV /密钥并加密/解密纯文本,如果这有所不同。

3 个答案:

答案 0 :(得分:4)

为了解决这个问题,通常会为每个cypertext随机生成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]

答案 1 :(得分:2)

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

答案 2 :(得分:-3)

AES256应该以256位(32字节)的块混合数据。由于您有很长的前导文本(> 32个字节)很少更改,因此使用加密方法会导致性能不佳。您可以解决此问题,但只要在前32个字节内发生变化,就会开始使用频繁更改的明文字符串。您可以创建一些随机种子和实际有用的数据。

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

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