在.NET 4.5中,可以选择使用随机字符串哈希码生成。 这意味着,在不同应用程序域中计算的相同字符串的哈希码将是不同的。 (见http://msdn.microsoft.com/en-us/library/jj152924.aspx)
问题是:这个选项的实际用途是什么? 换句话说,在什么情况下(场景)我需要打开它?
答案 0 :(得分:5)
我认为这样做的一般应用是防止针对散列机制的可能的DoS攻击。
由于GetHashCode()
在内部由Dictionary<,>
和“普通”数据使用,因此哈希值应该合理地分布,以便哈希冲突不会“太频繁”发生。当哈希冲突确实发生时,Dictionary<,>
会回退到使用相同哈希码的所有项目的线性搜索。
在可公开访问的应用程序中,对于具有散列机制知识的对手,可能会提交具有大量具有相同哈希码的字符串的请求,从而导致正常的O(1)查找变为O(N查找添加了这些值的任何字典。
对于Web应用程序,我相信标题和查询字符串参数之类的内容会添加到字典中以便应用程序快速访问,因此攻击者可以提交包含数千个具有冲突哈希值的参数的请求,从而产生请求比“正常”请求显着更多地消耗资源。这会对任何DoS尝试产生放大效应,即使攻击者只有相对适中的带宽,也可以进行攻击。
通过随机化每个AppDomain的哈希值,攻击者不太可能使用冲突哈希来制作字符串,从而防止此类攻击。
编辑地址评论
虽然MSDN文章没有提到它,但设置的意图并非提供让不同AppDomains创建不同字符串哈希的方法,这是防止第三方的安全功能从创建具有相同哈希的许多字符串。
在.NET 4.5之前(或禁用此设置),假设我运行的是与您相同的.NET版本,我的计算机上的"some string".GetHashCode()
将提供与您相同的值。由于使用的散列机制很简单(当然也不是加密安全散列),因此使用相同的散列进行逆向工程和创建大量字符串相对容易,然后使用上述方法来放大DoS攻击。
启用此设置后,会为字符串的哈希码生成添加随机元素,这使得攻击者更难以可靠地创建冲突字符串。
它是每个AppDomain的事实是哈希码具有某些必需属性的事实的副产品,例如,两个相同的字符串具有相同的哈希码因此,AppDomain为设置的效果提供了合理的边界,因为大多数应用程序在启用此设置的情况下都可以正常运行。
此新设置可能进一步解决此漏洞披露中引发的问题:CVE-2011-3414与在ASP.NET应用程序中利用散列冲突相关(我认为,该问题在其他.NET版本中已“修复”,限制了可以在请求中提供的密钥数量,防止攻击者创建如此多的冲突,从而显着降低性能)。 referenced paper特别提到缺乏随机字符串散列是导致该问题普遍存在的一个因素。