在Python中,HMAC比较如何不变



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-ectrenticated-ectrenticated-ectrenticated-

我的问题是,怎么可能不会恒定的时间?为了对其进行比较,有必要计算实际的HMAC,并且您不能一次计算Digest 1字符,对吗?最后,这只是一个简单的字符串比较,它比我的测试中的实际HMAC计算快2个数量级。那么这里的攻击表面到底在哪里?如果我不使用hmac.compare_digest()

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

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

memcmp的Linux manpage明确指出:

不要使用memcmp()比较安全数据,例如 加密秘密,因为所需的CPU时间取决于 相等的字节数。相反,执行比较的函数 在恒定时间内是需要的。一些操作系统提供了这样的 功能(例如Netbsd的consttime_memequal()),但没有此类功能 在POSIX中指定。在Linux上,可能有必要实施 这样的功能。)

一个足够确定的攻击者可以利用这一弱点,以找出您存储了什么哈希与正在发送的数据的哈希。

正时攻击使 forge签名成为可能。说,服务将授权信息存储在与客户共享的令牌中。如果客户可以更改这个令牌,他们可以访问原本不会拥有。为了防止这种情况,使用HMAC签名签名令牌,让服务器在接受返回的令牌之前验证返回的令牌。如果授权数据与签名不匹配,则拒绝令牌。

如果服务器执行此操作:

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

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

最新更新