对键和IV使用相同值的缺点

本文关键字:缺点 IV | 更新日期: 2023-09-27 18:07:29

我正在为。net实现一些简化加密和解密的类。

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

这很好,因为盐似乎总是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);
}

对键和IV使用相同值的缺点

好,只要您为每条消息使用一个新的随机创建的salt,您就接近于我可能要做的事情。随机盐意味着IV将随着每条新消息而改变,这意味着完全相同的消息每次传输将是不同的加密文本。所有的好。如果我是你,我会改变的一件事是,而不是使用DeriveBytes来获取密钥,然后获得IV,我会让DeriveBytes一起给出一组密钥和IV的大小,然后将它们分开并分别使用它们。静脉注射不应该对任何人保密。钥匙一定是。因此,如果您从相同的盐和密码中派生一次字节,然后将这些字节拆分为密钥和IV,攻击者在查看IV后仍然没有比以前更接近于知道密钥。

或者,您可以使用nonce来创建IV字节和key字节之间的已知排列。例如,原谅我的伪代码:

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

两种方法都是安全的。但是我只会把DeriveBytes设置为32个字节,然后用16个字节作为IV, 16个字节作为key。前16个字节中没有任何信息可以帮助攻击者计算接下来的16个字节。

是的,它违背了IV的目的。使用IV的目的是,如果你用相同的密钥加密相同的消息,你不会得到相同的密文。你也可以使用一个恒定的0值,它可以增加相同的安全性。

在这里,您使用相同的值为

    <
  • 键/gh>第四

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

你试图防御的事情是确保使用相同密钥的两个加密不会给出相同的密文。在您的示例中,只有当RNG生成两个相同的128位AES密钥时才会发生这种情况。

虽然这种可能性很低,但你不应该这样做。