【问题标题】:How could HMAC comparison ever not be constant-time in Python?在 Python 中,HMAC 比较怎么可能不是恒定时间的?
【发布时间】:2019-03-20 12:41:38
【问题描述】:

Python有专门比较HMAC来防止定时攻击的方法:https://docs.python.org/3.7/library/hmac.html#hmac.compare_digest

我在这里阅读了有关定时攻击的信息:https://security.stackexchange.com/questions/74547/timing-attack-against-hmac-in-authenticated-encryption

我的问题是,它怎么可能不是恒定时间?有必要计算实际的 HMAC 以便进行比较,而且您不能一次计算摘要 1 个字符,对吧?最后,它只是一个简单的字符串比较,比我测试中的实际 HMAC 计算快 2 个数量级。那么这里的攻击面到底在哪里呢?如果我不使用hmac.compare_digest(),有人可以举例说明实际漏洞在哪里吗?

【问题讨论】:

  • 因为 Python == 相等性测试不能保证它是恒定时间。
  • 所以基本上,你承认这是一个纯粹的技术正确性问题,实际上并不是一个实际问题......这和我想的差不多。
  • 嗯,不,我不是。我告诉你,使用== 会使你面临预言机定时攻击。

标签: python-3.x security hmac timing-attack


【解决方案1】:

最后,它只是一个简单的字符串比较,比我测试中的实际 HMAC 计算快 2 个数量级。

但它是不是恒定的时间。仅仅因为它们完成得很快并不意味着差异是不可测量的。对于bytes 值,Python 首先测试相等的长度和相等的第一个字节,然后使用memcmp 测试其余部分。对于字符串,Python 比较长度,然后是 kind(如果字符串每个字符使用 1、2 或 4 个字节),然后还使用 memcmp

memcmp 的 Linux 手册页明确指出:

不要使用memcmp() 来比较安全关键数据,例如 密码机密,因为所需的 CPU 时间取决于 相等的字节数。相反,执行比较的函数 需要在恒定时间内。一些操作系统提供这样的 函数(例如,NetBSD 的 consttime_memequal()),但没有这样的函数 在 POSIX 中指定。在 Linux 上,可能需要实现 自己有这样的功能。)

一个足够坚定的攻击者可以利用这个弱点来找出你存储的哈希值与它正在发送的数据的哈希值。

定时攻击使得伪造签名成为可能。比如说,服务将授权信​​息存储在与客户端共享的令牌中。如果客户端可以更改此令牌,则他们可以获得原本无法获得的访问权限。为了防止这种情况,令牌使用 HMAC 签名进行签名,让服务器在接受它为有效之前验证返回的令牌。如果授权数据与签名不匹配,则拒绝令牌。

如果服务器这样做:

auth_data, signature = split_token(token)
expected = hmac_signature(auth_data)
if signature == expected:
    # ...

然后攻击者可以检测伪造签名的多少字符与预期的签名匹配,并进行相应的调整。它们以XXXXX:000000... 开头,然后尝试XXXXX:1000000... 等,直到服务所用时间增加,表明它们具有匹配的第一个字符。然后可以更改第二个字符,直到完整的签名匹配。

【讨论】:

  • 如果攻击者已经有了摘要,这不是完全没有意义吗?他们可以在自己的计算机上完成。
  • @dvtan:不,攻击者没有摘要,它正在尝试找出如何创建新的哈希值。
  • @dvtan:您链接到一篇文章,该文章准确解释了攻击者没有摘要,也不想要摘要,它想知道如何生成 新的他们控制的数据摘要。
  • 哦,对了,我在考虑对密钥进行暴力攻击...我的错误 it_hurt_itself_in_confusion.jpeg
  • 我仍然认为这太理论化了,随机方差会完全掩盖实际实践中的任何时间差异
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
  • 2022-07-10
  • 1970-01-01
相关资源
最近更新 更多