是否可以在使用AES或RijndaelManaged的加密和解密算法中使用随机盐和随机iv?
我正在学习加密和解密算法,我尝试在C#中使用aes或rijndaelmanaged,有人说,如果您使用静态盐进行加密并重用IV,那将是不安全的。
public static byte[] encryptAES(byte[] bytesToBeEncrypted, byte[]
passwordBytes)
{
byte[] result = null;
byte[] salt = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream MS = new MemoryStream())
{
using (RijndaelManaged Rima = new RijndaelManaged())
{
Rima.KeySize = 256;
Rima.BlockSize = 128;
Rfc2898DeriveBytes RFCDB = new Rfc2898DeriveBytes(passwordBytes, salt,
1000);
Rima.Key = RFCDB.GetBytes(Rima.KeySize / 8);
Rima.IV = RFCDB.GetBytes(Rima.BlockSize / 8);
Rima.Mode = CipherMode.CBC;
using (CryptoStream CS = new CryptoStream(MS, Rima.CreateEncryptor(),
CryptoStreamMode.Write))
{
CS.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
CS.Close();
}
result = MS.ToArray();
}
}
return result;
}
public static byte[] decryptAES(byte[] bytesToBeDecrypted, byte[]
passwordBytes)
{
byte[] result = null;
using (MemoryStream memoryStream = new MemoryStream())
{
Rfc2898DeriveBytes rfc2898DeriveBytes = new
Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
Rima.Key = rfc2898DeriveBytes.GetBytes(Rima.KeySize / 8);
Rima.IV = rfc2898DeriveBytes.GetBytes(Rima.BlockSize / 8);
using (CryptoStream cryptoStream = new CryptoStream(memoryStream,
Rima.CreateDecryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cryptoStream.Close();
}
result = memoryStream.ToArray();
}
return result;
}
private static RijndaelManaged Rima = new RijndaelManaged
{
KeySize = 256,
BlockSize = 128,
Mode = CipherMode.CBC
};
private static byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
我试图找到一种使用随机或动态盐和随机IV的方法。
答案 0 :(得分:1)
是的...使用静态IV或盐是个坏主意。原因是,使用一致的IV或盐对您使用该IV或盐发送的所有邮件都具有“告诉”或一致的效果。出于所有实际目的,您可以生成随机的salt和IV,但是解密器需要知道它们的值。从技术上讲,它们不是秘密的,您可以将其发送给收件人。如果使用它们对数据库中保存的数据进行加密,则需要在消息中保留盐和IV。
在分组密码中,它们用于“屏蔽”消息的开头,因此您不会在密文中看到重复出现的模式。如果在所有消息上使用相同的salt和IV(假设您使用相同的密码或密钥),则以相同的几个字符开头的每条消息的密文开头将具有相同的字节数...并且这就是嗅出您的消息的开始。第一个块的比特被反馈到下一个密文块中……因此,随机的前几块消息会更完全地扰乱您的消息……使模式分析变得更加困难。
顺便说一句,您正在使用旧示例中的一些旧代码。我建议您查看this question,以了解在.Net中加密/解密数据的更合适的方法。您会在一些答案中看到一些代码,这些答案看起来很像您所拥有的,但是有一些重要的区别。这个问题中的讨论和最常见的答案值得一读。