存储盐和哈希密码的安全性如何?

13

如果您查看了ASP.NET成员资格系统的表模式,您会发现它们存储原始密码的哈希值以及用于生成它的盐。请参见下面的模式:

dbo.aspnet_Membership

ApplicationId
UserId
Password
PasswordFormat
PasswordSalt
MobilePIN
Email
. . .
  • 如果攻击者获得数据库,他是否更容易从盐和哈希密码中破解原始密码?

  • 在查看了一些记录后,似乎为每个密码生成了一个新的盐。这有何意义?

  • 您会推荐这种方法,还是在代码中硬编码恒定的盐?

相关

如果攻击者知道盐,盐对安全性是否无用?


1
小提示,你必须在某个地方存储盐。 - user7116
@sixlettervariables 是的,框架将其存储在密码列旁边的下一列中,请查看问题中的模式。 - Deeptechtons
我指出了为什么这两者会一起出现。 - user7116
@sixlettervariables 哈哈,我的问题也是关于那个的。 - Deeptechtons
3个回答

14

关于ASP.NET密码/哈希/盐值存储的具体细节,请参见例如http://msdn.microsoft.com/en-us/library/aa478949.aspx

攻击者可以“允许”知道盐值-您的安全性必须设计得即使知道盐值也仍然安全。

盐有什么作用?

盐有助于防御使用预先计算的“彩虹表”进行暴力破解攻击。
盐使暴力破解对攻击者来说更加昂贵(在时间/内存方面)。
计算这样的表格是昂贵的,并且通常只有在可以用于多次攻击/密码时才会这样做。
如果您对所有密码使用相同的盐,攻击者可能会预先计算这样的表格,然后将您的密码暴力破解为明文...
只要为要存储哈希值的每个密码生成一个新的(最佳加密强度的)随机盐,就没有问题。

如果您想进一步增强安全性
您可以多次计算哈希(哈希哈希等)-这不会花费太多时间,但它会使暴力攻击/计算“彩虹表”变得更加昂贵...请不要自己发明-有经过验证的标准方法,例如参见http://en.wikipedia.org/wiki/PBKDF2http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

注意:

使用这样的机制现在已成为必须,因为“CPU时间”(可用于类似彩虹表/暴力破解攻击)变得越来越普遍(例如,亚马逊云服务位列全球前50名最快超级计算机之一,可由任何人以相对较少的费用使用)!


哇,我得出的答案和你差不多,只不过你写得更好。 :) - Jordan Reiter
@Deeptechtons,由于您将盐值与哈希值一起存储,所以只需查找该用户的盐值,重新计算出哈希值(使用数据库中的输入密码和盐值),并将结果与数据库中存储的哈希值进行比较...如果相等,则一切正常,如果不相等,则输入的密码是错误的...您甚至可以在错误密码输入达到一定次数后锁定账户,以增加安全性。 - Yahia
@Yahia 很抱歉打扰您,但我无法理解派生字节哈希算法,您能否花点时间为我提供一个示例。MSDN上的示例让我感到困惑,他们为什么要使用加密,获取盐和哈希密码是否真的必要? - Deeptechtons
1
使用 @Deeptechtons 代码可以获取一个 Base64 编码的哈希字符串,使用你的 salt 和以下代码:Convert.ToBase64String((new Rfc2898DeriveBytes(你的密码, 你的 Salt)).GetBytes(20)) - Yahia
1
不错的回答,但我不会将最后一部分表述为可选项 - 每个网站都应该使用像PBKDF2或SCrypt这样的适当哈希强化。 - Nick Johnson
显示剩余4条评论

8
盐的目标是减缓黑客攻击数据库的可能性,而不是完全防止。但是它确实大大减缓了黑客的攻击速度!从仅有几秒钟到,根据算法、盐的长度和其他因素,可能需要数小时、数月或甚至宇宙寿命。

话虽如此,你必须将盐与加盐密码一起存储,否则事后无法验证密码。

以下是您可以采取的几种方法,使整个过程更加安全:

  1. 永远不要使用相同的盐。每个密码应该有不同的盐
  2. 使用长的盐。GUID通常是一个受欢迎的选项。我通常通过获取随机数的MD5哈希来生成它们
  3. 如果您愿意,可以多次运行哈希算法。这会延长破解密码所需的时间。

+1 很好的回答 :-) 我唯一不太舒服的是“自己实现”,特别是在安全方面,应该使用经过验证的方法,而不是试图“发明”(这可能会导致安全性不强化,甚至有时会削弱安全性)。 - Yahia
@Jordan回答了我的一个疑问:“你必须将盐值与加盐密码一起存储,否则事后无法验证密码。” - Deeptechtons

0

我不会使用MD5,SHA1更安全。但说实话,如果你了解安全和密码学,这些都是单向函数。所以大多数人不会浪费太多时间攻击一个不能给他带来收益的东西 :D。如果你认为这样还不够安全,可以使用RSA,但要使用非常非常长的数字作为密钥。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接