IV + Salt 可以一样吗?

信息安全 加密 初始化向量
2021-08-20 18:53:26

在我的加密应用程序中,我有密码创建位:

PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10000, keyLength);

稍后在实际的加密部分:

cipher.init(Cipher.ENCRYPT_MODE, secret, ivSpec);

初始化向量需要随机字节,salt 需要随机字节,我可以为 salt 和 IV 使用相同的(加密安全的)随机字节,还是会以某种方式削弱加密?- 如果可以的话,它会使存储更容易一些。

我不是在谈论在多条消息上重用 IV 或盐,对于每条单独的消息,都会生成一个新的字节数组,但是我可以为每条单独的消息加倍并为盐 + 使用相同的新生成的字节吗?第四?

例如:

消息 1:随机字节 = h6ds .... Salt = h6ds / IV = h6ds

消息 2:随机字节 = djs9 .... Salt = djs9 / IV = djs9

消息 3:随机字节 = 9sdf .... Salt = 9sdf / IV = 9sdf

... 等等

2个回答

对于每条加密的消息,IV 应该是唯一的,所以不,如果您打算使用从该密码生成的密钥加密多个秘密,则不能将盐重用作 IV。重用IV充其量会泄漏有关明文的信息,最坏的情况是会完全破坏您的加密方案(取决于您使用的模式),所以是的,无论如何,如果它被重用,它确实会削弱加密。

但是,如果您重复使用它,并且它只会被使用一次,那么不,相同的随机值在其他地方用作盐这一事实应该对加密的强度完全没有影响。

编辑添加:有一个警告我认为不适用于这种特定情况,但应该提及。由于您使用 KDF 生成密钥,因此盐构成了密钥强度的一部分。如果 IV 暴露给攻击者(考虑到问题的措辞,我认为这里不是这种情况),那么在计算候选密钥以及从弱密码容易受到字典攻击。然而,如果盐/IV 只是被储存,并且可以合理地认为妥协其中之一,那么强度不受影响的初始前提仍然成立。

使用 PBKDF2 的盐作为 IV 进行使用从 PBKDF2 获得的密钥的加密运行依赖于 PBKDF2 像随机预言机一样运行,从而“隔离”这两种用法,防止发生不良交互。这不是一个研究太多的属性,但它是合理的,因为 PBKDF2 是对 HMAC 的大量嵌套调用,而 HMAC 是随机预言机的通常候选者。

然而,另一种设计更易于分析:只需让 KDF 为密钥IV 生成足够的字节。即,从盐和密码生成 32 个字节:16 个字节用于加密密钥,16 个其他字节用于 IV。这样一来,您就可以将存储费用保持在同一水平(只有一种盐,IV 没有额外的空间),并且很明显,您的 IV 没有做任何时髦的事情。作为额外的奖励,如果您将 KDF 切换到另一个对盐值和大小有严格要求的 KDF,您仍然可以获得适当长度的 IV 用于您的加密。

通常的警告适用:

  • PBKDF2 不是一个很好的基于密码的密钥派生函数。特别是,它的运行时间与输出大小(带有阈值)成比例增加,这意味着从 PBKDF2 中获取超过 20 个字节可能会迫使您将迭代次数减半,这对安全性不利。此外,PBKDF2 很容易在 GPU 上进行优化。Bcrypt 会是更好的选择对于“任意输出长度”部分,将密码散列函数与良好(快速)的 KDF(例如HKDF )结合起来。

  • 当你进行加密时,你可能也需要一个MAC这可能是一件棘手的事情。