为什么HashMap需要一个加密安全的哈希函数?



我正在读一本关于HashMap哈希函数的 Rust 书,我无法理解这两句话。

默认情况下,HashMap 使用加密安全的哈希函数,该函数可以抵抗拒绝服务 (DoS( 攻击。这不是可用的最快哈希算法,但随着性能下降而来的更好安全性的权衡是值得的。

我知道什么是加密安全的哈希函数,但我不明白它背后的原理。据我了解,一个好的HashMap哈希函数应该只有三个属性:

  • 确定性(同一对象具有相同的哈希值(
  • 非常快,
  • 哈希值中的位分布均匀(这意味着它将减少冲突(

在加密安全哈希函数中,其他属性在哈希表的 99%(甚至可能是 99.99%(时间内并不真正相关。

所以我的问题是:">抵抗DoS攻击和更好的安全性"是什么 "甚至在哈希图的上下文中意味着?

让我们从后面开始:你如何做一个哈希图?

多年来,基于哈希泛洪的各种软件堆栈遭到了多次攻击。如果您知道站点由哪个框架提供支持,因此使用了哪个哈希函数,并且此哈希函数在加密上不安全,那么您可以离线预先计算大量散列到相同数量的字符串。

然后,您只需将此集合注入站点,对于每个(简单(请求,它都会执行不成比例的大量工作,因为插入 N 个元素需要 O(N2( 操作。


Rust 是事后诸葛亮的,因此注意默认避免这种攻击,理由是真正需要性能HashMap的用户只需切换哈希函数即可。

假设我们使用HashMap在Web应用程序中存储一些用户数据。假设用户可以以某种方式选择(部分(密钥- 也许密钥是用户名或上传文件的文件名或类似的东西。

如果我们不使用加密安全的哈希函数,这意味着攻击者可能会手工创建多个输入,这些输入都映射到相同的输出。当然,哈希映射必须处理碰撞,因为它们是自然发生的。

但是,当不自然地发生许多冲突时,哈希映射实现可能会做一些奇怪的事情。例如,查找某些键的运行时可能为O(n(。或者哈希映射可能认为它必须因为所有冲突而增长;但是增长并不能解决问题,因此哈希映射会增长,直到使用所有内存。无论哪种情况,这都很糟糕。哈希映射只是假设从统计学上讲,很少发生碰撞。

当然,这不是"窃取用户数据"攻击 - 至少不是直接攻击。但是,如果系统的一部分很弱,这使得攻击者更容易找到其他弱点。

加密安全的哈希函数可以防止这种攻击,因为攻击者不可能创建映射到相同值的多个密钥(至少不尝试所有密钥(。


与哈希表的 99%(甚至 99.99%(时间并不真正相关。

是的,可能。但这很难平衡。我想我们都会同意,如果 20% 的用户由于不安全的哈希函数而在他们的应用程序中遇到安全问题(而 80% 的用户不在乎(,那么使用"默认安全"方法仍然是一个好主意。5%/95%呢?1%/99%呢?很难说门槛在哪里,对吧?

关于这个问题已经有很多讨论。因为是的,大多数人只注意到哈希映射的缓慢。也许我上面描述的情况非常罕见,默认情况下不值得减慢所有其他用户的代码速度。但这已经决定了,默认哈希函数不会改变,幸运的是你可以选择自己的哈希函数。

如果服务器应用程序将用户输入(例如在 Web 应用程序中发布数据(存储在哈希表中,恶意用户可能会尝试提供大量具有相同哈希值的输入,从而导致大量哈希冲突,从而显着减慢映射上的操作,以至于它可以用作 DoS 攻击(例如本文中所述(。

如果哈希在加密上是安全的,则攻击者将更难尝试查找具有相同哈希值的输入。

最新更新