在.NET 4.5中,可以选择使用随机字符串哈希码生成.这意味着,在不同应用程序域中计算的相同字符串的哈希码将是不同的.(参见http://msdn.microsoft.com/en-us/library/jj152924.aspx)
问题是:这个选项的实际用途是什么?换句话说,在什么情况下(场景)我需要打开它?
我相信这一般的应用是为了防止可能的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版本中已"修复",限制了密钥数量可以在请求中提供,防止攻击者创建如此多的冲突,从而显着降低性能).该参考文章特别提到缺乏随机字符串散列为促进这一问题的普遍性的一个因素.