I am implementing some classes for .NET that (among other things) simplify encryption and decryption.
我正在实现.NET的一些类,其中包括简化加密和解密。
My current algorithm creates an 8-byte salt, and uses that salt with the password to generate both the key and IV. I then store the salt, unencrypted, with my encrypted data.
我当前的算法创建了一个8字节的salt,并使用该salt和密码生成密钥和IV。然后我将未加密的盐与我的加密数据一起存储。
This is nice because the salt appears to always be 8 bytes and that's all the overhead it adds to my encrypted data. However, is there any downside to using the same value for both my key and IV? Is there a better way?
这很好,因为salt似乎总是8个字节,这是它添加到我的加密数据的所有开销。但是,对我的密钥和IV使用相同的值是否有任何缺点?有没有更好的办法?
Relevant code:
相关代码:
SymmetricAlgorithm algorithm = CreateAlgorithm();
byte[] salt = CreateSalt();
byte[] keyBytes = DeriveBytes(salt, algorithm.KeySize >> 3);
byte[] ivBytes = DeriveBytes(salt, algorithm.BlockSize >> 3);
Supporting code:
支持代码:
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 个解决方案
#1
2
OK, as long as you use a new, randomly created salt for each message, you are close to what I might do. The random salt means the IV will change with each new message, and this means that the exact same message will be different crypto-text each transmission. All good. The one thing I would change if I were you is instead of using DeriveBytes to get the key and then to get the IV, I would have DeriveBytes give a set of bytes the size of the key and IV together, then split them and use them separately. The IV should not have to be secret from anyone. The key must be. So if you DeriveBytes once from the same salt and password, then split those bytes into key and IV, the attacker is still no closer to knowing the key after looking at the IV than he was before.
好的,只要你为每条消息使用一个新的,随机创建的盐,你就会接近我可能做的事情。随机盐意味着IV将随着每个新消息而改变,这意味着完全相同的消息将在每次传输时加密文本。都好。如果我是你,我会改变的一件事是不是使用DeriveBytes来获取密钥然后获得IV,我会让DeriveBytes给出一组大小与键和IV一起的字节,然后将它们拆分并使用它们分别。 IV不应该是任何人的秘密。关键必须是。因此,如果您使用相同的盐和密码对DeriveBytes进行一次,然后将这些字节拆分为密钥和IV,攻击者在查看IV之后仍然比以前更接近知道密钥。
Alternatively, you could use a nonce to create a known permutation between the IV bytes and the key bytes. For example, excuse my pseudocode:
或者,您可以使用随机数在IV字节和密钥字节之间创建已知的排列。例如,请原谅我的伪代码:
IV = DeriveBytes(salt + password + "IV")
key = DeriveBytes(salt + password + "key")
Either way is secure. But I would just DeriveBytes on, say, 32 bytes and then use 16 of them for the IV and 16 of them for the key. There is no information in the first 16 bytes that will help an attacker calculate the next 16 bytes.
无论哪种方式都是安全的。但是我只需要DeriveBytes,比方说,32字节,然后使用其中16个用于IV,其中16个用于密钥。前16个字节中没有信息可以帮助攻击者计算接下来的16个字节。
#2
1
Yes, it defeats the purpose of the IV. The IV is used so if you encrypt the same message with the same key you don't get the same ciphertext. You might as well just use a constant value of 0
, it adds the same amount of security.
是的,它违背了IV的目的。使用IV是因为如果使用相同的密钥加密相同的消息,则不会获得相同的密文。您也可以使用常量值0,它会增加相同的安全性。
#3
1
In your case here you are using the same value for your
在你的情况下,你使用相同的值
- Key
- 键
- IV
- IV
Conceptually this is a bad idea because the IV is supposed to be non-secret, and different for each encryption. You've solved the "different for each encryption", but you have it identical to your key.
从概念上讲,这是一个坏主意,因为IV应该是非秘密的,并且每个加密都不同。您已经解决了“每次加密的不同”,但您的密钥与密钥完全相同。
The thing you're trying to defend against is making sure that two encryptions with the same key will not give the same ciphertext. In your case, this will only happen if the RNG generates two identical 128-bit AES keys.
你要防范的是确保使用相同密钥的两次加密不会产生相同的密文。在您的情况下,只有在RNG生成两个相同的128位AES密钥时才会发生这种情况。
While the odds of this are low, you should just not have it.
虽然这种可能性很低,但你应该没有它。
#1
2
OK, as long as you use a new, randomly created salt for each message, you are close to what I might do. The random salt means the IV will change with each new message, and this means that the exact same message will be different crypto-text each transmission. All good. The one thing I would change if I were you is instead of using DeriveBytes to get the key and then to get the IV, I would have DeriveBytes give a set of bytes the size of the key and IV together, then split them and use them separately. The IV should not have to be secret from anyone. The key must be. So if you DeriveBytes once from the same salt and password, then split those bytes into key and IV, the attacker is still no closer to knowing the key after looking at the IV than he was before.
好的,只要你为每条消息使用一个新的,随机创建的盐,你就会接近我可能做的事情。随机盐意味着IV将随着每个新消息而改变,这意味着完全相同的消息将在每次传输时加密文本。都好。如果我是你,我会改变的一件事是不是使用DeriveBytes来获取密钥然后获得IV,我会让DeriveBytes给出一组大小与键和IV一起的字节,然后将它们拆分并使用它们分别。 IV不应该是任何人的秘密。关键必须是。因此,如果您使用相同的盐和密码对DeriveBytes进行一次,然后将这些字节拆分为密钥和IV,攻击者在查看IV之后仍然比以前更接近知道密钥。
Alternatively, you could use a nonce to create a known permutation between the IV bytes and the key bytes. For example, excuse my pseudocode:
或者,您可以使用随机数在IV字节和密钥字节之间创建已知的排列。例如,请原谅我的伪代码:
IV = DeriveBytes(salt + password + "IV")
key = DeriveBytes(salt + password + "key")
Either way is secure. But I would just DeriveBytes on, say, 32 bytes and then use 16 of them for the IV and 16 of them for the key. There is no information in the first 16 bytes that will help an attacker calculate the next 16 bytes.
无论哪种方式都是安全的。但是我只需要DeriveBytes,比方说,32字节,然后使用其中16个用于IV,其中16个用于密钥。前16个字节中没有信息可以帮助攻击者计算接下来的16个字节。
#2
1
Yes, it defeats the purpose of the IV. The IV is used so if you encrypt the same message with the same key you don't get the same ciphertext. You might as well just use a constant value of 0
, it adds the same amount of security.
是的,它违背了IV的目的。使用IV是因为如果使用相同的密钥加密相同的消息,则不会获得相同的密文。您也可以使用常量值0,它会增加相同的安全性。
#3
1
In your case here you are using the same value for your
在你的情况下,你使用相同的值
- Key
- 键
- IV
- IV
Conceptually this is a bad idea because the IV is supposed to be non-secret, and different for each encryption. You've solved the "different for each encryption", but you have it identical to your key.
从概念上讲,这是一个坏主意,因为IV应该是非秘密的,并且每个加密都不同。您已经解决了“每次加密的不同”,但您的密钥与密钥完全相同。
The thing you're trying to defend against is making sure that two encryptions with the same key will not give the same ciphertext. In your case, this will only happen if the RNG generates two identical 128-bit AES keys.
你要防范的是确保使用相同密钥的两次加密不会产生相同的密文。在您的情况下,只有在RNG生成两个相同的128位AES密钥时才会发生这种情况。
While the odds of this are low, you should just not have it.
虽然这种可能性很低,但你应该没有它。