当然 SHA1 比 MD5 更安全,但在大多数情况下它还不够安全。
您可能会发现视频 How NOT to Store Passwords by Computerphile 很有用 - 时长 9 分 24 秒。
您必须意识到,在身份验证和访问控制方面有很多内容需要涵盖,因此只有一个好的散列方案是不够的。
关于存储密码。
如您所知,您不存储密码。实际上,在存储密码时,一般来说,您希望使用为此目的优化的现代算法来存储密码的加盐哈希。对于盐,可以将其与散列一起存储,对于盐值尽可能使用随机值。
注意:出于安全目的生成随机值时,请使用加密安全生成器(例如 RandomNumberGenerator for .NET - example 的子类)。这个随机数生成器被设计成难以预测。虽然标准随机数生成器是可重复的(即使用System.Random,您只需要生成所有值的种子,而猜测种子所需要的只是使用相同种子生成的足够连续值)。
另请注意:大多数哈希都经过优化以快速计算,MD5 和 SHA1 都属于该类别。 您应该选择一个不那么快的,以便在尝试破解您的密码时,攻击将花费合理的时间来计算哈希值。
这样的算法之一是 BCrypt - 其他包括 Scrypt 和 PBKDF2 - 在使用 C# 中的 BCrypt 时,您会发现使用 BCrypt to Hash Your Passwords: Example for C# and SQL Server 的文章很有用。如果您无法使用 BCrypt 或类似算法,您至少应该使用 SHA2 的变体(SHA256、SHA512 等)。
附录:您可以使用 BLC 中可用的类HMACSHA256 作为密钥派生函数,将您的盐作为密钥传递。这比附加或前置盐(可能落到Length extension attacks)更可取。也就是说,如果您使用 HMAC,并且您的哈希算法容易受到长度扩展攻击(已知或将被发现),那么您的系统是安全的。 MD5、SHA1 和 SHA2 一样容易受到这种攻击。 SHA3 不是。遗憾的是 SHA3 不包含在 BLC 中(不,它不是 SHA384),您可以从 Multiformats.Hash 或 HashLib 获取它。我不得不提一下,SHA3 也被设计成在硬件中实现时速度很快。请记住,对于密码来说,使用慢速哈希会更好。
附录:Argon2
作为it was pointed a year ago,此答案应更新为提及Argon2。我确实在那之前写了原始答案。
当时,我还没有找到我愿意推荐的 C# 实现。由于这个答案引起了我的注意,我又看了看,不再是这样了。
您可以使用Isopoh.Cryptography.Argon2,它具有完全托管的代码(它不是用于 C++ 实现的 C# 绑定,而是完整的 C# 代码),适用于所有主要平台,并且有 Nugets 可用。
注意事项:
- 使用
Argon2Version.Nineteen。这是修复已知漏洞的 Argon2 v.1.3 (Nineteen = 0x13)。
- 使用
Argon2Type.DataDependentAddressin (Argon2d),或使用Argon2Type.DataIndependentAddressing (Argon2i) 和TimeCost >= 10。 Argon2d 理论上容易受到侧通道攻击,因此不建议在客户端机器上运行代码。 Isopoh.Cryptography.Argon2 通过使用操作系统调用来防止敏感内存移动到虚拟内存/页面文件/交换并尽快将其归零来缓解这种情况。另一方面,Argon2i 有一个时间-内存权衡漏洞,它允许通过使用更多内存来更快地计算哈希值。论文Towards Practical Attacks on Argon2i and Balloon Hashing 表明,即使在 Argon2 v.1.3 中,您也需要 10 次迭代/遍才能使漏洞利用效率低下。
以下是一些推荐阅读:
还有视频:Crypto is Back! - Google 技术讲座 - 2009 年 8 月 5 日 - 时长 54 分 32 秒。
关于找回密码。
首先:不要。密码恢复选项的重点不是恢复密码,而是恢复对应用程序的访问。那么...如何恢复对应用程序的访问权限?
很高兴你问。您需要的是另一种验证用户身份的方法。这可能是第二因素身份验证(从安全问题到使用硬件密钥生成器的任何事情)。然而,通常做的是向第三方提供资源,例如邮件。
因此,您想知道用户是否是该用户之前声称拥有的电子邮件(或手机或其他任何东西)的所有者。为此,您向该电子邮件(或其他)发送代码(通常称为令牌或 cookie)。这必须是带有加密安全生成器的随机生成的代码,这样除了该电子邮件的所有者(或其他任何人)之外,其他任何人都无法知道该代码是什么。
现在,如果用户向您的应用程序展示该代码,您几乎确定它是正确的用户。
几乎 因为:电子邮件(或其他)可能已存储在不安全的位置。为了缓解这种情况,您希望对代码(cookie 或令牌)设置时间限制。此外,如果代码已被使用,它应该不再次工作。为了获得额外的安全性,您可以向 CAPTCHA 提供资源,以确保此代码不是来自幸运的机器人。
有关此主题的更多信息(此链接也在上面提供):