像 MD5、SHA 和 SHA1 之类的快速哈希算法的用意并不在安全性——保护重要的信息,特别是密码,哈希算法必须有意地减慢反向暴力破解速度。 Troy Hunt 是一位微软的 MVP,它演示了 SqlMembershipProvider 所提供的密码哈希值如何易于被暴力破解。
SqlMembershipProvider 是 VS 2010 中 ASP.NET web 应用程序模板中的默认成员(membership)提供程序。Troy 在他的文章《我们的密码哈希值没有遮挡(Our password hashing has no clothes)》中演示了经过SqlMembershipProvider 中SHA1 哈希算法处理的密码安全性是如何被破解的,其中使用的是GPU、名为 hashkiller 的字典以及暴力破解算法。在规模为 40000 条的真实密码样本中(来自于之前的一次攻击),算法在 45 分钟内破解了 24710 个,占总体样本的 67%。 其中包括被认为是很强壮的密码:
像“volleyball6”,有 11 个字符,两种字符类型。甚至还有“zaq1@WSX”——由八个字符组成,其中有大写、小写、数字和符号,肯定足以通过大多数安全策略,但是即便被存储为“安全的”哈希值,也完全没用。
问题在于你拥有了可能的密码字典之后可以快速创建新的哈希值,并且硬件变得越来越快。
那么如何来解决这个问题呢? 密钥延伸(Key stretching),通过多次迭代哈希算法,能够提供一种方式来让哈希算法变得足够慢,使得暴力破解更加困难。 Bcrypt 和 PBKDF2 都是这样的算法——它们叫做适应性算法,因为通过增加迭代的次数,会随着时间推移而变得更慢(因为硬件变得更快)。 Bcrypt.NET 实现了前者,而 DefaultMembershipProvider 实现了后者。 DefaultMembershipProvider 对 SHA1 使用了 1000 次迭代,它是 VS2012 的 ASP.NET MVC 4 模板政所提供的默认选项。Troy 的文章《.NET 中更强的密码哈希算法(Stronger password hashing in .NET)》说明了如何使用这些方法,以及如何把应用程序迁移到使用更强壮的哈希算法,而不会破坏你的身份验证过程。
评论