提问人:SLaks 提问时间:12/4/2009 更新时间:7/9/2014 访问量:8795
Secure Password Hashing [已关闭]
Secure Password Hashing [closed]
问:
我需要在 .Net WinForms 应用程序中存储单个密码的哈希值。
最安全的方法是什么?
特别:
- 盐、HMAC 还是两者兼而有之?
- 多少盐?
- 多少次迭代?
- 什么编码?(密码为纯 ASCII)
我假设算法应该是 SHA512 或 HMACSHA512。
答:
RNGCryptoServiceProvider 生成一个随机盐,然后用盐对密码进行 SHA512,最后存储密码哈希和相应的盐,如果以后想验证某些文本是否等于存储的密码。
评论
哈希和盐。如果你只散列,你可能会受到彩虹攻击的攻击(反向有查找),而盐使这变得更加困难(随机盐是最好的。对于编码,您可能需要对生成的字节数组进行 Base64 或十六进制编码。如果只是尝试将字节数组存储为 Unicode,则可能会面临某些数据丢失的风险,因为并非所有模式都是有效字符。这也提供了一种更简单的方法来比较哈希值(当您想要验证时,只需比较 base64 或十六进制字符串,而不是比较字节数组)
增加回合数除了减慢攻击者的速度之外并没有多大作用。但是,如果您丢失或需要重新创建哈希算法,将来重用哈希值也会变得更加困难。您可以查看标准密码哈希,例如 unix 系统上的 crypt。这允许您更改哈希算法,甚至可以支持版本控制。
但同样,对于大多数应用程序来说,简单的哈希 + 盐就足够了。
对于具有大量密码的服务器端实现,您绝对应该使用可调的迭代方法,例如 bcrypt。这篇关于该主题的著名文章仍然(大部分)相关:
http://www.securityfocus.com/blogs/262
对于独立应用程序中的单个密码,其中存储位置可能已经受到系统自己的身份验证系统保护,我认为这并不重要。单个强哈希值可能就足够了,而且添加盐也很容易,没有理由不这样做。
我可以推荐 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);
严格看更安全:
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 或其他一些不太预期的转换。
注意:这主要是开玩笑写的,但仍然应该包含一些事实。
我认为你应该坚持开放标准。在目前的哈希方案中,OpenLDAP使用的“{ssha}”非常安全,应用广泛。你可以在这里找到描述,
http://www.openldap.org/faq/data/cache/347.html
大多数 LDAP 库都实现了此方案。
使用至少 128 位或更长的安全随机盐对哈希进行加盐,以避免彩虹攻击并使用 BCrypt、PBKDF2 或 scrypt。PBKDF2 已获得 NIST 认证。
问题是 MD5 速度很快。它的现代竞争对手也是如此,比如 SHA1 和 SHA256。速度是一种设计 现代安全哈希的目标,因为 哈希值是几乎 每个密码系统,通常得到 对每个数据包执行的需求或 基于每条消息。
速度正是您在密码哈希函数中不想要的。
快速密码验证功能是一个问题,因为它们可以使用暴力破解进行攻击。使用上述所有算法,您可以控制“慢”
评论
Rfc2898DeriveBytes
您可以遵循已发布的标准,例如 pkcs#5。有关简短说明,请参阅 http://en.wikipedia.org/wiki/PKCS,有关 RFC,请参阅 https://www.rfc-editor.org/rfc/rfc2898。
这是一个 API,它可以完成您需要/想要的一切:)
评论