当 IV 已经随机生成并与加密数据一起存储时,为什么还需要 AES-CBS 的盐?

信息安全 加密 AES 红宝石 初始化向量
2021-08-21 19:23:42

我正在查看这段代码并遇到了这些评论,这些评论说没有盐的加密是不安全的。当您已经为每个值使用随机 IV 时,为什么会不安全?我认为评论可能不正确,但它是一个受欢迎的宝石,所以我不确定。我认为它key真的被视为一个password,我只是想验证一下。

https://github.com/attr-encrypted/encryptor/blob/master/lib/encryptor.rb#L57

  if options[:iv]
    cipher.iv = options[:iv]
    if options[:salt].nil?
      # Use a non-salted cipher.
      # This behaviour is retained for backwards compatibility. This mode
      # is not secure and new deployments should use the :salt options
      # wherever possible.
      cipher.key = options[:key]
    else
      # Use an explicit salt (which can be persisted into a database on a
      # per-column basis, for example). This is the preferred (and more
      # secure) mode of operation.
      cipher.key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(options[:key], options[:salt], 2000, cipher.key_len)
    end
  else
    cipher.pkcs5_keyivgen(options[:key])
  end

我打算从头开始写一些东西,并且只使用基础库。我的密钥来自SecureRandom.base64(32),我将其存储在代码中,然后 Base64 对其进行解码以获得二进制密钥,并将其用于加密/解密,以及每个数据元素的随机 IV。我认为我不需要为此加盐。想确认。

2个回答

当你这样做时,你需要盐和静脉注射……两种不同的动作,一个需要盐,另一个需要静脉注射。这就是你的情况。

salt涉及将密码转换为密钥这就是您的示例代码中使用的内容:PBKDF2是一个基于密码的密钥派生函数与使用密码的任何东西一样,PBKDF2 需要可配置的慢度(即“2000”参数)以及salt 授予的唯一性。这是密码散列的一个子案例,在此处进行了解释

实际加密需要IV 。CBC模式是一种顺序算法,其中每个数据块首先与前一个块的处理输出进行异或。它必须从某个地方开始......所以IV是用于第一个块的任意“前一个块”。

一般来说,CBC模式需要一个均匀随机的IV,并且无法被处于选择要加密的部分数据的攻击者预测(对SSL的BEAST攻击就是这种类型)。但是,只有当同一个密钥至少使用两次时才会出现问题。因此,以下两个技巧可能适用,并且避免了沿加密文件传输 IV 的需要:

  • PBKDF2 可用于生成可配置长度的输出。可以使用 PBKDF2 为密钥IV 生成足够的字节。
  • 使用传统的固定IV(例如“全零”)。

当特定加密密钥仅使用一次时,这两种方法才有效。这意味着如果使用相同的密码加密两个文件,则必须为每个文件生成一个新的随机盐。意味着如果密码到密钥的转换在计算上很昂贵(而且应该如此),并且许多文件必须使用相同的密码进行加密,那么总成本可能会变得过高。

如果相同的盐用于多个文件(具有相同的密码)(*),那么结果是所有这些文件都将使用相同的密钥,这很好......只要每个文件也有自己的四。所以 IV 必须以某种方式存储在文件头中。另一方面,如果所有文件都使用相同的盐,那么也许您可以共享该盐的存储空间?

通用、安全的方法是在每次加密运行时使用随机 IV(从加密强 PRNG 生成),而不管密钥是如何获得的。这避免了对密钥生成过程以及它在整个协议中发生的频率做出隐含的假设。此外,如果要使用“相同密码”将许多文件作为批处理加密,这允许将密码到密钥的转换相互化:只要每个文件都有自己的随机 IV,相同的密钥(从密码中派生一次) ,用一种盐)可以安全地应用于所有人。这就是在TLS(1.1 版及更高版本)中发生的事情:所有记录在给定的连接中使用相同的密钥加密,但每条记录都有自己的 IV,这是安全的(在 TLS 1.0 中,每条记录通过从前一个加密记录的末尾复制它来获得自己的 IV,这很容易受到BEAST,因为这些 IV 然后可以通过观察来预测;在 TLS 1.1+ 中,每条记录都有一个新的、特定的随机 IV)。

(*) 切勿为不同的密码重复使用盐值。绝不。

你理解正确。您找到的代码包含一个常见的命名错误。我最初误读了代码。汤姆·李克是对的。代码并没有搞砸,而是在散列时使用盐,然后在加密时使用 IV。

许多人将术语“盐”和“初始化向量”混为一谈。它们具有相同的目的,但在技术上用于不同的操作。散列时使用盐,加密时使用IV。在这两种情况下,目的都是通过添加随机输入来防止相同的输入总是导致相同的输出。

如果您在加密的上下文中看到“盐”,它可能意味着 IV。如果您在散列的上下文中看到 IV,它可能是盐。


需要指出的是,在加密时,您需要保护 IV。有一种攻击可以使用未受保护的 IV 来学习加密数据。BEAST(除非我记错了)就是这种攻击的一个例子。您可以使用 GCM、XST 或其他一些较新的加密模式自动获得这种保护。如果您使用 CBC 等较旧的加密模式,您需要自己使用签名或 HMAC 保护 IV。