Not*_*ame 11 hash cryptography
我最近阅读了一篇关于密码散列和 salting 的文章,其中解释了(在"SlowEquals代码如何工作?"下)必须使用SlowEquals函数来比较输入的密码的哈希值与数据库中密码的哈希值.
据我所知,使用SlowEquals函数是因为它使用XOR而不是==因此将检查两个字符串中的每个字符,而不是在第一个不匹配的字符上失败.
有两件事我不明白:
Iri*_*ium 12
算法比较两个哈希值的所有字节的事实仅仅是实现的结果,并且与XOR的使用无关(即,即使使用==,也可以编写一个算法来比较所有字节而不会破坏第一个不匹配).使用XOR旨在避免在循环体中引入分支指令,这可能会显示由于CPU的分支预测而导致的匹配字节数的详细信息(尽管这是否是一个问题在某种程度上取决于特定的实现,以及它编写的指令).
使用随机sleep()来屏蔽在第一次不匹配时返回的散列检查的定时并不真正起作用,因为通过采用更多样本仍然可以在给定点处区分匹配与不匹配.为了论证,如果我们假设我们在[0..100]范围内均匀分布一个随机数毫秒,并且某个位置的匹配需要2ms,并且该位置的不匹配仅需1ms(作为算法)早退出).通过足够的采样,我们可以区分匹配和不匹配的情况,因为我们会观察到在不匹配情况下的响应范围为[1..101] ms,但在匹配情况下为[2..102] ms(假设我们可以完美地计算时间响应) .当然,现实世界的观测会遭受抖动和其他随机来源,但仍有可能观察到偏见.
那么当然只有实际的考虑因素 - 为什么要引入睡眠,random等,当相对较小的修改应该导致它在恒定的时间运行,并消除定时攻击?
TL;DR - 在比较密码哈希时使用 SlowEquals 并不重要。
如果你试图验证一个非散列的秘密,那么使用“SlowEquals”对于阻止定时攻击很有价值。
但是,如果您使用的是计算量足够大的正确密码哈希(PBKDF2,50k+ 次迭代),那么这并不重要。为什么?因为密码散列“假设违规”。即使攻击者窃取/知道散列和盐,找到散列到该值的明文密码也太耗时,因此密码仍然受到保护。这就是加密哈希的全部意义所在,即使被盗也无法使用。当然,有人可以使用定时攻击来计算哈希值,但这并不重要,因为他们仍然无法计算出密码。
再加上锁定功能,帐户在 X 次无效尝试后被锁定(3-10 次,任您选择),对散列密码的定时攻击从毫无价值变为毫无价值。