为啥 HashMap 需要一个加密安全的散列函数?
Posted
技术标签:
【中文标题】为啥 HashMap 需要一个加密安全的散列函数?【英文标题】:Why does HashMap need a cryptographically secure hashing function?为什么 HashMap 需要一个加密安全的散列函数? 【发布时间】:2019-02-10 13:17:54 【问题描述】:我在看一本关于HashMap
hashing functions的Rust书,这两句话看不懂。
默认情况下,HashMap 使用加密安全的哈希函数,可以抵抗拒绝服务 (DoS) 攻击。这不是可用的最快的哈希算法,但性能下降带来的更好的安全性是值得的。
我知道什么是加密安全哈希函数,但我不明白它背后的原理。据我了解,HashMap
的良好哈希函数应该只有三个属性:
密码安全散列函数中的其他属性在 99%(甚至 99.99%)的情况下与散列表并不真正相关。
所以我的问题是:什么是“抵抗 DoS 攻击和更好的安全性” " 甚至在 HashMap 的上下文中是什么意思?
【问题讨论】:
您可能会喜欢阅读bugs.php.net/bug.php?id=60623、arstechnica.com/information-technology/2011/12/… 和nikic.github.io/2014/12/22/… 或搜索“php5 哈希表冲突”:) 这里有点归结为意见:一个人假设是否更好地为每个人提供“安全”(以性能为代价 95% 不需要安全所有时间)而不是给每个人“快”(以错过需要“安全”而不是“快”的地方为代价)。 @GhostCat 如果 5% 的人需要安全,仍然可以provide a customBuildHasher
。
@TimDiekmann 看,我们如何在这里进行讨论?潜在问题有多种选择,并且在某种程度上,我们进入了对如何最好地解决问题有不同意见的业务。在我看来,这个问题有点好,固执己见。
@GhostCat 这就是为什么我已经标记为基于意见的原因 ;)
【参考方案1】:
如果服务器应用程序将用户输入(例如在 Web 应用程序中发布数据)存储在哈希表中,恶意用户可能会尝试提供大量具有相同哈希值的输入,从而导致大量输入哈希冲突,从而显着减慢地图上的操作,以至于它可以被用作 DoS 攻击(如this article 中所述)。
如果哈希在密码学上是安全的,那么攻击者将很难找到具有相同哈希值的输入。
【讨论】:
【参考方案2】:让我们向后开始:你如何 DoS 一个 HashMap?
多年来,基于Hash Flooding 的各种软件堆栈发生了多次攻击。如果您知道站点由哪个框架提供支持,因此使用了哪个散列函数,并且该散列函数在密码学上不安全,那么您可以离线预先计算大量的字符串哈希到相同的数字。
然后,您只需将此集合注入站点,对于每个(简单)请求,它都会执行大量工作,因为插入 N 个元素需要 O(N2) 次操作。
Rust 的构思是事后诸葛亮,因此注意避免这种攻击默认情况下,理由是真正需要HashMap
之外的性能的用户只需切换哈希函数即可。
【讨论】:
【参考方案3】:假设我们使用HashMap
将一些用户数据存储在网络应用程序中。 假设用户可以以某种方式选择(部分)密钥 - 可能密钥是用户名或上传文件的文件名或类似内容。
如果我们不使用加密安全哈希函数,这意味着攻击者可能制作多个输入,所有输入都映射到相同的输出。当然,哈希映射必须处理冲突,因为它们是自然发生的。
但是当不自然地发生许多冲突时,哈希映射实现可能会做一些奇怪的事情。例如,查找某些键可能需要 O(n) 的运行时间。或者哈希图可能认为它必须因为所有的冲突而增长;但是增长并不能解决问题,所以哈希映射增长直到所有内存都用完。无论哪种情况,这都很糟糕。哈希图只是假设在统计上很少发生冲突。
当然,这不是“窃取用户数据”攻击——至少不是直接攻击。但如果系统的某一部分薄弱,攻击者就更容易发现其他薄弱环节。
加密安全的哈希函数可以防止这种攻击,因为攻击者不可能制作多个映射到相同值的密钥(至少在没有尝试所有密钥的情况下不能)。
在 99%(甚至可能 99.99%)的时间里与哈希表并不真正相关。
是的,可能。但这很难平衡。我想我们都会同意,如果 20% 的用户会因为不安全的哈希函数在他们的应用程序中遇到安全问题(而 80% 的人不在乎),那么使用“默认安全”方法仍然是一个好主意。 5%/95% 怎么样? 1%/99% 呢?很难说阈值在哪里,对吧?
已经有很多关于这个的讨论。因为是的,大多数人只注意到哈希图的缓慢性。也许我上面描述的情况非常罕见,默认情况下减慢所有其他用户的代码是不值得的。不过这个已经决定了,默认的hash函数不会改变,还好你可以选择自己的hash函数。
【讨论】:
以上是关于为啥 HashMap 需要一个加密安全的散列函数?的主要内容,如果未能解决你的问题,请参考以下文章