首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从Rfc2898DeriveBytes生成AES IV

从Rfc2898DeriveBytes生成AES IV
EN

Stack Overflow用户
提问于 2021-05-17 17:53:09
回答 4查看 803关注 0票数 1

我正在使用Rfc2898DeriveBytes生成一个AES密钥和iv。但是,我听说iv不应该依赖密码。我现在就是这样做的:

代码语言:javascript
运行
复制
byte[] salt = GenerateRandomBytes(32); // Generates 32 random bytes
using (Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(plainStrPassword, salt)) {
    byte[] aesKey = rfc.GetBytes(32); 
    byte[] iv = rfc.GetBytes(16);    // Should I do this or generate it randomly?
}

我的问题是:从iv生成Rfc2898DeriveBytes可以(安全)吗?或者我应该使用RNGCryptoServiceProvider随机生成它

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-05-17 19:29:51

不,从您获得密钥的同一源派生IV是不安全的。IV的存在使得在同一密钥下对相同消息的加密产生不同的密文。

您应该使用加密安全的随机源(例如您标识的RNGCryptoServiceProvider )来派生IV并与密文通信(通常是以一个字节流的形式预置到密文中,或者以更结构化的文件格式在单独的字段中进行通信)。

票数 1
EN

Stack Overflow用户

发布于 2021-05-17 20:01:05

让我们看看你的代码;

代码语言:javascript
运行
复制
byte[] salt = GenerateRandomBytes(32); // Generates 32 random bytes
using (Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(plainStrPassword, salt)) {
    byte[] aesKey = rfc.GetBytes(32); 
    byte[] iv = rfc.GetBytes(16);    // Should I do this or generate it randomly?
}
  • 随机盐-好
  • Rfc2898DeriveBytes和salt;只要用户密码有很好的强度,这是很好的。强度(不是熵!)派生的密钥不能超过密码的强度。
  • 打电话给GetBytes(32)以获得关键的--很好,这就是我们所期望的。
  • 呼叫GetBytes(16)进行IV -

这也很好,因为

对该方法的重复调用不会生成相同的键;相反,附加cb参数值为20的GetBytes方法的两个调用相当于一次调用cb参数值为40的GetBytes方法。

对于每一种加密,您可以通过调用GetBytes(16)继续获得一个新的IV。当然,这是有限度的。PKKDF2标准限制输出2^32-1 * hLen,参见RFC 8018

输出某些部分作为IV,并保留某些部分作为加密密钥没有什么问题。已经有大量使用PBKDF2和non的密码方案被打破,甚至密码哈希和salt已经被知道。

如果你害怕这不是一个好主意,那么你可以使用任何一个;

  • 生成两个盐类,导出IV和加密密钥,分别作为密码;
代码语言:javascript
运行
复制
byte[] saltForKey = GenerateRandomBytes(32); // Generates 32 random bytes
using (Rfc2898DeriveBytes rfcKey = new Rfc2898DeriveBytes(plainStrPassword, saltForKey)) {
    byte[] aesKey = rfcKey.GetBytes(32);

byte[] saltForIV = GenerateRandomBytes(32); // Generates 32 random bytes
using (Rfc2898DeriveBytes rfcIV = new Rfc2898DeriveBytes(plainStrPassword, saltForIV)) { 
    byte[] iv = rfcIV.GetBytes(16);    // Should I do this or generate it randomly?
}
  • 生成随机盐并导出加密密钥,jus生成一个随机IV
代码语言:javascript
运行
复制
byte[] salt = GenerateRandomBytes(32); // Generates 32 random bytes for Salt
byte[] IV = GenerateRandomBytes(16); // Generates 16 random bytes of IV

using (Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(plainStrPassword, salt)) {
    byte[] aesKey = rfc.GetBytes(32); 
}

请注意,您没有定义加密模式。对于像这样的模式

  • CTR模式,96位的现在,和32位计数器是常见的.为此,计数器/LFSR也可以生成96位的nonce。确保(键,IV)对永远不会发生。
  • CBC模式下,现在必须是随机和不可预测的。以上这些都是可以的。
  • 当然,您应该忘记这些,使用经过身份验证的加密模式,如AES-GCM、Cha20-Poly1305。如果您担心IV重用,那么使用AES-GCM-SIV,它只能泄漏您发送的相同消息,其他任何信息都不会泄漏。SIV模式只是慢了一倍,因为它必须通过明文才能派生IV,然后执行加密。
票数 2
EN

Stack Overflow用户

发布于 2021-05-17 18:11:57

许多密码算法被表示为迭代算法。例如,在CBC模式下用块密码加密消息时,每个消息“块”首先是XORed与前一个加密块,然后XOR的结果被加密。第一个块没有“前一个块”,因此我们必须提供一个常规的备用“零块”,我们称之为“初始化向量”。一般来说,IV是开始运行算法所需的任何数据,而不是秘密的(如果它是秘密的,我们称之为“密钥”,而不是IV)。

IV是一个任意常数,所以任何值都可以工作。确保您的加密器和解密器使用相同的值。要获得更多信息,您可以参考以下链接:

https://crypto.stackexchange.com/questions/732/why-use-an-initialization-vector-iv

https://crypto.stackexchange.com/questions/3965/what-is-the-main-difference-between-a-key-an-iv-and-a-nonce

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67574726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档