拒绝使用Key和IV的相同值?

时间:2015-08-12 02:05:07

标签: c# .net encryption encryption-symmetric

我正在为.NET实现一些类(除其他外)简化加密和解密。

我当前的算法创建了一个8字节的salt,并使用该salt和密码生成密钥和IV。然后,我将未加密的盐与我的加密数据一起存储。

这很好,因为salt似乎总是8个字节,并且它增加了我加密数据的所有开销。但是,对于我的密钥和IV使用相同的值是否有任何缺点?还有更好的方法吗?

相关代码:

SymmetricAlgorithm algorithm = CreateAlgorithm();
byte[] salt = CreateSalt();
byte[] keyBytes = DeriveBytes(salt, algorithm.KeySize >> 3);
byte[] ivBytes = DeriveBytes(salt, algorithm.BlockSize >> 3);

支持代码:

private static readonly int SaltLength = 8;

internal byte[] CreateSalt()
{
    byte[] salt = new byte[SaltLength];
    using (RNGCryptoServiceProvider generator = new RNGCryptoServiceProvider())
    {
        generator.GetBytes(salt);
    }
    return salt;
}

public byte[] DeriveBytes(byte[] salt, int bytes)
{
    Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(Password, salt, 1000);
    return derivedBytes.GetBytes(bytes);
}

3 个答案:

答案 0 :(得分:2)

好的,只要你为每条消息使用一个新的,随机创建的盐,你就会接近我可能做的事情。随机盐意味着IV将随着每个新消息而改变,这意味着完全相同的消息将在每次传输时加密文本。都好。如果我是你,我会改变的一件事是不是使用DeriveBytes获取密钥然后获得IV,我会让DeriveBytes给出一组字符大小的密钥和IV一起,然后拆分并使用它们分别。 IV不应该是任何人的秘密。关键必须是。因此,如果您使用相同的盐和密码DeriveBytes一次,然后将这些字节拆分为密钥和IV,攻击者在查看IV之后仍然比以前更接近知道密钥。

或者,您可以使用随机数在IV字节和密钥字节之间创建已知的排列。例如,请原谅我的伪代码:

IV = DeriveBytes(salt + password + "IV")
key = DeriveBytes(salt + password + "key")

无论哪种方式都是安全的。但是我只需要DeriveBytes,比方说32字节,然后使用其中的16个用于IV,其中16个用于密钥。前16个字节中没有信息可以帮助攻击者计算接下来的16个字节。

答案 1 :(得分:1)

是的,它违背了IV的目的。使用IV是因为如果使用相同的密钥加密相同的消息,则不会获得相同的密文。您也可以使用0的常量值,它会增加相同的安全性。

答案 2 :(得分:1)

在这种情况下,您使用的是

相同的值
  • 关键
  • IV

从概念上讲,这是一个坏主意,因为IV应该是非机密的,并且对于每个加密都是不同的。您已经解决了"对于每种加密" 的不同,但您的密钥与您的密钥相同。

您尝试防范的事情是确保使用相同密钥的两次加密不会提供相同的密文。在您的情况下,只有在RNG生成两个相同的128位AES密钥时才会发生这种情况。

虽然这种可能性很低,但你应该没有它。