所以,在 ASP.NET 中,
System.WebHelpers.Crypto.HashPassword("123456");
将创建一个每次都是唯一的散列、加盐字符串。这很棒;这意味着如果有人设法获得散列密码(例如,在 SQL 注入(inject)攻击中),他们将无法使用查找表来查找原始密码。然而,据我所知,他们仍然能够轻松地编写代码来尝试在本地进行暴力破解,而无需涉及受害者的服务器,例如:
foreach(string passwordToTry in BigListOfCommonPasswords)
if (Crypto.VerifyHashedPassword(stolenHash,passwordToTry)) return passwordToTry;
...所以在调用 HashPassword 时添加您自己的额外盐不是更好吗,额外的盐存储在数据库之外,例如:
System.WebHelpers.Crypto.HashPassword("123456"+getSaltFromWebConfig());
...,或者出于某种原因这毫无意义?在我看来,让上述暴力攻击变得更加困难是值得的,但我从未在 Crypto.HashPassword
的使用示例中的任何地方看到过这个想法,所以我是否遗漏了什么?
编辑:这不是 The necessity of hiding the salt for a hash 的副本。这个问题是在询问未隐藏的盐是否对它有任何用处。我不是在争论存储在与散列密码相同的位置的盐是否有用,或者将未加盐的密码传递给 Crypto.HashPassword 是否有用。 我真正想知道的是,添加你自己的、额外的盐,存储在别处(即使它对每个用户都是一样的),在 Crypto.HashPassword 提供的保护层之上提供了额外的保护层。
在暴露数据库的 SQL 注入(inject)攻击的情况下,例如 web.config 文件中的附加盐仍将受到保护(或者至少需要完全不同的攻击才能访问它)。
System.WebHelpers.Crypto.HashPassword("123456"+getSaltFromWebConfig());
使哈希密码对攻击者的用处远小于
System.WebHelpers.Crypto.HashPassword("123456");
对于某些类型的攻击,在计算能力或编程时间方面没有太多额外成本。
最佳答案
您描述的盐通常称为胡椒。关于是否使用胡椒的问题在这里得到了非常完整的回答:
Best Practices: Salting & peppering passwords?
总而言之,您不应该使用辣椒,因为:
- 您不能更改胡椒的值,因为哈希函数是一种方式。
- 添加胡椒会有效地改变散列算法,这只能由专家来完成。
但是,如果获得静态 secret 比获得密码哈希更难的假设成立,则还有另一种可以提高安全性的选择。与其添加胡椒粉,不如使用标准对称算法简单地加密散列和盐的组合。这解决了上述两个问题,同时在加密 key 未被泄露的情况下仍提高了安全性。
关于asp.net - 为什么不应该对传递给 Crypto.HashPassword 的密码加盐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35315668/