认证加密中对 HMAC 的定时攻击?

信息安全 加密 hmac 定时攻击
2021-08-16 14:10:43

对我的另一个问题的回答中,注意到在验证加密中检查 HMAC 时使用标准字符串比较函数的类会使该类容易受到针对 HMAC 的定时攻击。

我无法理解这种针对经过身份验证的加密的 HMAC 的定时攻击是如何成为问题的?

首先,攻击者应该知道这些实现(在这种特殊情况下,源只是简单地发布),所以唯一的秘密就是密钥。按照这种推理,实现中的恒定时间比较函数如何防止任何事情发生?(我希望攻击者简单地删除它,如果他甚至会使用相同的代码)。

其次,如果我将实现视为黑盒,则比较是针对具有 PBKDF2 派生密钥的数据的 HMAC。尝试对 HMAC 进行定时攻击不会 a) 与尝试暴力破解受 PBKDF2 保护的密码一样慢 b) 不会真正披露任何有助于尝试解密数据的信息?(HMAC 甚至附加到密文中,可供所有有权访问加密数据的人使用)。

那么,我在这里遗漏了什么,为什么在这种情况下定时攻击被认为是需要防范的风险?


快速更新:
我了解定时攻击的工作原理,但我不明白在解密函数如下所示的场景中使用定时攻击会获得什么:

/**
 * @param binary $data Where $data = salt, IV, encrypted data, HMAC(salt, IV, encrypted data)
 * @param string $password The decrypt-password
 * @return string|null plain text if data was successfully decrypted, null otherwise
 */
function decrypt($data, $password) {
    ...
}
2个回答

它允许存在存在伪造的可能性。攻击者可以在不知道 HMAC 密钥的情况下为所选消息创建有效的 HMAC。

基本上,攻击的工作方式是这样的:

  1. 攻击者发送一条消息和一个 HMAC(实际上只是一个与 HMAC 长度相同的字节序列),并对来自解密系统的响应进行计时。

  2. 攻击者然后重复发送相同的消息和相同的伪 HMAC,除了他现在迭代 HMAC 的第一个字节的每个 (256) 可能值。

  3. 如果解密系统在发现字节之间不匹配时立即返回错误,则其中一个迭代(具有与解密系统计算的相同的第一个字节值的迭代)应该需要稍长的时间才能返回。如果攻击者可以检测到这种差异,他现在就知道给定解密系统的 HMAC 密钥的消息的正确 HMAC 的正确第一个字节。

  4. 攻击者发送相同的消息和 HMAC,这次使用已知正确的第一个字节,遍历第二个字节,直到再次找到导致解密系统响应错误的时间稍长的字节。攻击者现在知道正确 HMAC 的第二个字节。

  5. 对 HMAC 中的每个连续字节进行冲洗和重复,直到为攻击者选择的消息(无密钥)派生出有效的 HMAC。

这就是为什么 HMAC 比较需要是恒定时间的,在返回响应之前将提交的 HMAC 的所有字节与计算的 HMAC 进行比较。这样,无论任何错误字节的位置如何,出错的时间总是相等的。攻击者不再有办法分辨不正确的字节是什么或在哪里。

更新

在您呈现的特定场景中,HMAC 正在为您提供完整性保护,或者是“身份验证加密”中的“身份验证”部分。如果它可以被攻击者伪造,密文可以在你不知情的情况下被修改,你不再拥有经过身份验证的加密,而是有效的未经身份验证的加密,并且容易受到选择密文的攻击。

风险在于攻击者可以伪造数据。换句话说,他们可以提出自己的密文,然后计算出预期的 HMAC 以使您的系统接受有效的输入。

HMAC 的全部意义在于,只有作为密钥的所有者才能“签署”数据。但是,如果应用程序泄露了有关输入的预期 HMAC 的信息,那么攻击者实际上可以“签署”他们自己的数据。

简单地说,它的工作原理是这样的:

攻击者提出了一些数据并希望您的系统接受它。为此,他们需要知道正确的 HMAC。由于攻击者没有密钥,他们不能简单地计算 HMAC。但是,通过测量细微的时间差异,他们可以“询问”您的系统有关预期值的信息:

  • 攻击者:“我有这段数据,我猜 HMAC 是从字节 0x00 开始的。这个对吗?”
  • 你:“没有。”
  • 攻击者:“HMAC 是否以 0x01 开头?”
  • 你:“没有。”
  • ...
  • 攻击者:“HMAC 是否以 0xAB 开头?”
  • 你:“是的,第一个字节是正确的。”
  • 攻击者:“好的。下一个字节是 0x00 吗?”
  • 你:“没有。”
  • ...

最后,攻击者知道所有字节。

问题是应用程序不只是拒绝错误的 HMAC。它实际上通过告诉攻击者 HMAC应该是什么样子来帮助攻击者。


查看您的更新,您似乎通常不了解 HMAC 的用途以及它为何如此重要。

假设没有 HMAC。在这种情况下,您只会保护数据的机密性,而不是完整性人们可以操纵现有的密文或想出自己的密文,您的应用程序会很高兴地将其转换为碰巧出现的任何明文。在许多情况下,这是一个严重的问题。考虑一个包含用户 ID 的加密会话 cookie:您不希望人们更改它。

因此,您添加 HMAC 作为一种“签名”,以防止用户篡改密文。您需要保密性完整性。但是,如果用户可以为任意数据找出正确的 HMAC,那么整个练习就毫无意义。您失去了完整性保护并返回到纯加密。现在,任何人都可以再弄乱密文了。