Secure Password Hashing [已关闭]

Secure Password Hashing [closed]

提问人:SLaks 提问时间:12/4/2009 更新时间:7/9/2014 访问量:8795

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章用事实和引文来回答。

去年关闭。

社群在 2 个月前审查了是否重新打开这个问题,并将其关闭:

原始关闭原因未解决

我需要在 .Net WinForms 应用程序中存储单个密码的哈希值。

最安全的方法是什么?

特别:

  • 盐、HMAC 还是两者兼而有之?
  • 多少盐?
  • 多少次迭代?
  • 什么编码?(密码为纯 ASCII)

我假设算法应该是 SHA512 或 HMACSHA512。

.NET 安全 密码 哈希

评论

0赞 tjmoore 12/4/2009
不能建议最安全(尽管这是一个你真正想走多远的问题),但要确保它绝对是一个真正的单向哈希,并且足够安全,即使你需要非常努力地获得密码,即使你也无法获得密码。例如,如果有大客户发臭或要求获取密码。
0赞 SLaks 12/4/2009
我假设 SHA512 是一个安全的哈希值。
1赞 Tim Sylvester 12/4/2009
我不认为“最安全”真的是合适的问题。这是一个根据所保护数据的重要性在安全性、复杂性和用户便利性之间找到平衡的问题。我们是在谈论保护银行帐号还是视频游戏分数?可能的攻击者是脚本小子还是 NSA?
2赞 SLaks 12/4/2009
@Tim:用户便利性不是一个因素。我会有一个密码;我只是在问最好的散列方法。
0赞 Sam Saffron 12/4/2009
阅读:stackoverflow.com/questions/800685/...

答:

2赞 Darin Dimitrov 12/4/2009 #1

RNGCryptoServiceProvider 生成一个随机盐,然后用盐对密码进行 SHA512,最后存储密码哈希和相应的盐,如果以后想验证某些文本是否等于存储的密码。

评论

0赞 SLaks 12/4/2009
您认为我不应该使用 HMAC 或使用迭代哈希吗?
2赞 Darin Dimitrov 12/4/2009
在我看来,带有随机盐的 SHA-512 足够强大。这里有一篇不错的文章 aspheute.com/english/20040105.asp,只需使用 SHA-512 而不是 SHA-1。
0赞 Noon Silk 12/4/2009
HMAC 引入了不需要的问题(密钥)。
4赞 Sam Saffron 12/4/2009
bcrypt 是一种明显更好的方法
3赞 D.W. 9/17/2011
SHA512 不是一个好的选择:它太快了。bcrypt 更好。
1赞 Matthew Whited 12/4/2009 #2

哈希和盐。如果你只散列,你可能会受到彩虹攻击的攻击(反向有查找),而盐使这变得更加困难(随机盐是最好的。对于编码,您可能需要对生成的字节数组进行 Base64 或十六进制编码。如果只是尝试将字节数组存储为 Unicode,则可能会面临某些数据丢失的风险,因为并非所有模式都是有效字符。这也提供了一种更简单的方法来比较哈希值(当您想要验证时,只需比较 base64 或十六进制字符串,而不是比较字节数组)

增加回合数除了减慢攻击者的速度之外并没有多大作用。但是,如果您丢失或需要重新创建哈希算法,将来重用哈希值也会变得更加困难。您可以查看标准密码哈希,例如 unix 系统上的 crypt。这允许您更改哈希算法,甚至可以支持版本控制。

但同样,对于大多数应用程序来说,简单的哈希 + 盐就足够了。

5赞 Tim Sylvester 12/4/2009 #3

对于具有大量密码的服务器端实现,您绝对应该使用可调的迭代方法,例如 bcrypt。这篇关于该主题的著名文章仍然(大部分)相关:

http://www.securityfocus.com/blogs/262

对于独立应用程序中的单个密码,其中存储位置可能已经受到系统自己的身份验证系统保护,我认为这并不重要。单个强哈希值可能就足够了,而且添加盐也很容易,没有理由不这样做。

8赞 Svish 12/4/2009 #4

我可以推荐 BCrypt.net。非常易于使用,您可以调整进行哈希处理所需的时间,这太棒了!

// Pass a logRounds parameter to GenerateSalt to explicitly specify the
// amount of resources required to check the password. The work factor
// increases exponentially, so each increment is twice as much work. If
// omitted, a default of 10 is used.
string hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));

// Check the password.
bool matches = BCrypt.CheckPassword(candidate, hashed);
1赞 gwell 12/4/2009 #5

严格看更安全:

Salt, HMAC, or both?

两者都会更安全。由于HMAC的密钥可以被认为是盐,因此两者都会有点多余,但仍然更安全,因为它需要更多的工作才能破解。

How much salt?

每一点盐都会使需要在彩虹表中维护的组合加倍,以便轻松破解密码。但是,由于只有一个密码,并且只有一个盐,因此可能不需要更多密码。HMAC 使用基础哈希的块大小作为其密钥大小,SHA512 为 1024 位。块的大小应该足够好,但将其加倍或三倍会使使用彩虹表破解密码变得更加困难。

How many iterations?

越多越好。当然,更多的迭代意味着需要更长的时间才能确定是否输入了正确的密码,但计算机速度很快,用户不介意在验证密码时等待几秒钟。进行更多迭代意味着破解密码的人也必须进行更多迭代。

What encoding? (The password is plain ASCII)

还不如加密(使用 AES)过度迭代、过度加盐、HMAC 的、超级安全的密码及其加盐,只是为了让它更难。使加密密码哈希和密钥的密码是应出现在可执行文件中的字符串的某种组合,例如“RNGCryptoServiceProvider”或“System.Security.Cryptography”。在编码时,我们不妨将其转换为十六进制,或 base64,或者更好的是 base-36 或其他一些不太预期的转换。

注意:这主要是开玩笑写的,但仍然应该包含一些事实。

1赞 ZZ Coder 12/4/2009 #6

我认为你应该坚持开放标准。在目前的哈希方案中,OpenLDAP使用的“{ssha}”非常安全,应用广泛。你可以在这里找到描述,

http://www.openldap.org/faq/data/cache/347.html

大多数 LDAP 库都实现了此方案。

32赞 Sam Saffron 12/4/2009 #7

使用至少 128 位或更长的安全随机盐对哈希进行加盐,以避免彩虹攻击并使用 BCryptPBKDF2scrypt。PBKDF2 已获得 NIST 认证

引用:Archive.org:http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html

问题是 MD5 速度很快。它的现代竞争对手也是如此,比如 SHA1 和 SHA256。速度是一种设计 现代安全哈希的目标,因为 哈希值是几乎 每个密码系统,通常得到 对每个数据包执行的需求或 基于每条消息。

速度正是您在密码哈希函数中不想要的。

快速密码验证功能是一个问题,因为它们可以使用暴力破解进行攻击。使用上述所有算法,您可以控制“慢”

评论

0赞 rook 12/11/2009
速度是消息摘要功能中非常重要的一部分。NIST在选择下一个标准的消除过程中排除了缓慢的消息摘要。
9赞 Sam Saffron 12/11/2009
有时我想知道人们在投反对票之前是否阅读了我的答案
3赞 Keith 8/7/2012
我要补充一点,PBKDF2 有一个原生的 .Net 实现,这使得它可能是目前最好的选择。Rfc2898DeriveBytes
1赞 atk 12/4/2009 #8

您可以遵循已发布的标准,例如 pkcs#5。有关简短说明,请参阅 http://en.wikipedia.org/wiki/PKCS,有关 RFC,请参阅 https://www.rfc-editor.org/rfc/rfc2898

1赞 thashiznets 10/4/2012 #9

这是一个 API,它可以完成您需要/想要的一切:)

https://sourceforge.net/projects/pwdtknet