安全密码哈希

时间:2009-12-03 17:39:42

标签: .net security passwords hash

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

最安全的方法是什么?

特别是:

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

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

9 个答案:

答案 0 :(得分:32)

使用至少128位或更长时间的安全随机盐来填充哈希值,以避免彩虹攻击并使用BCryptPBKDF2scrypt。 PBKDF2附带NIST approval

引用: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。速度是一种设计   现代安全哈希的目标,因为   哈希几乎是一个基石   每个密码系统,通常得到   需求 - 按每个数据包执行或   基于每个消息。

     

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

快速密码验证功能是一个问题,因为它们可能会受到暴力攻击。使用上面的所有算法,您可以控制“慢度”

答案 1 :(得分:8)

我可以推荐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);

答案 2 :(得分:5)

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

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

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

答案 3 :(得分:1)

RNGCryptoServiceProvider生成随机盐,然后使用salt SHA512密码,最后存储密码哈希和相应的盐,如果您想稍后验证某些文本等于存储的密码

答案 4 :(得分:1)

哈希和盐。如果你只是哈希你可能被彩虹攻击攻击(反向查找)和盐使这更难(随机盐将是最好的。)对于你的编码你可能想要Base64或十六进制编码你的结果字节数组。如果您只是尝试将字节数组存储为Unicode,则可能会冒一些数据丢失的风险,因为并非所有模式都是有效字符。这也允许更简单的比较哈希的方法(只需要比较base64或十六进制字符串,而不是比较字节数组)

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

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

答案 5 :(得分:1)

严格看待更安全:

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或其他一些不太预期的转换。

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

答案 6 :(得分:1)

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

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

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

答案 7 :(得分:1)

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

答案 8 :(得分:1)

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

https://sourceforge.net/projects/pwdtknet