4

在 .NET 4.5 中,可以选择使用随机字符串哈希码生成。这意味着,在不同的应用程序域中计算的相同字符串的哈希码将是不同的。(见http://msdn.microsoft.com/en-us/library/jj152924.aspx

问题是:这个选项的实际用途是什么?换句话说,在什么场景(scenarios)我需要开启它?

4

1 回答 1

5

我相信这个的一般应用是为了防止可能的针对散列机制的 DoS 攻击。

由于GetHashCode()在内部被Dictionary<,>, 和“正常”数据使用,散列值应该合理分布,以便散列冲突不会“太频繁”发生。当哈希冲突确实发生时,Dictionary<,>回退到对具有相同哈希码的所有项目进行线性搜索。

在可公开访问的应用程序中,了解散列机制的攻击者可能会提交包含大量具有相同散列码的字符串的请求,从而导致通常的 O(1) 查找变为 O(N) 查找任何添加了这些值的字典。

特别是对于 Web 应用程序,我相信诸如标头和查询字符串参数之类的东西会被添加到字典中,以便应用程序快速访问,因为这样攻击者可以提交包含数千个参数的请求以及冲突的哈希值,从而导致请求明显更多比“正常”请求更需要资源。这对任何 DoS 尝试都有放大作用,即使攻击者只有相对有限的可用带宽,也允许攻击发生。

通过随机化每个 AppDomain 的哈希值,攻击者不太可能使用冲突哈希来制作字符串,从而防止此类攻击。

编辑寻址注释:

虽然 MSDN 文章没有提到它,但设置的目的不是提供一种让不同的 AppDomains 创建不同的字符串哈希的方法,它是一种安全功能,可以防止第三方创建许多具有相同哈希的字符串。

在 .NET 4.5 之前(或禁用此设置),只要我运行与您相同的 .NET 版本,"some string".GetHashCode()在我的机器上将给出与您相同的值。由于使用的散列机制很简单(当然不是加密安全的散列),因此逆向工程并创建许多具有相同散列的字符串相对容易,然后如上所述使用这些来放大 DoS 攻击。

启用此设置后,随机元素将添加到字符串的哈希码生成中,使攻击者更难以可靠地制作碰撞字符串。

它是每个 AppDomain 的事实是哈希码具有某些必需属性这一事实的副产品,例如,两个相同的字符串具有相同的哈希码。因此,AppDomain 为设置的效果提供了一个合理的边界,因为大多数应用程序在启用此设置的情况下将运行得非常好。

此新设置可能会进一步解决此漏洞披露中提出的问题:与利用 ASP.NET 应用程序中的哈希冲突相关的CVE-2011-3414(我相信,通过限制密钥数量,该问题在其他 .NET 版本中已“修复”可以在请求中提供,防止攻击者创建如此多的冲突,从而显着降低性能)。引用的论文特别提到缺乏随机字符串散列是导致该问题广泛传播的一个因素。

于 2012-10-29T13:30:01.073 回答