【问题标题】:manage a secure password管理安全密码
【发布时间】:2024-01-18 22:10:01
【问题描述】:

我的程序要求输入密码并将其保存在文本文件中,下次我运行程序时,如果文本文件存在,它会要求输入密码,然后我将其与文本文件中的密码进行比较。

现在,在现实世界中,我知道没有使用文本文件,但我不知道如何改进我的技术,因为无论加密算法如何,每个人都可以读取文本文件,并将其他解决方案作为注册表项一样的。

这是一个练习,我的目的是了解如果我正在编写商业应用程序,那么我应该使用什么技术来存储具有更强大安全性的密码?

【问题讨论】:

    标签: c# passwords password-protection


    【解决方案1】:

    您将密码存储在哪里并不重要,只要您只存储密码的哈希值即可。文本文件会做得很好,重要的是您使用盐和具有成本因素的慢散列函数。像 MD5 或 SHA* 这样的算法不适合散列密码,因为它们太快,因此很容易被暴力破解。

    BCrypt.NET 实现了 BCrypt 算法,该算法旨在散列密码。它将自动添加加密安全的盐并将其包含在生成的 BCrypt 哈希中。

    // Hash a new password for storing in the database.
    // The function automatically generates a cryptographically safe salt.
    string hashToStoreInDb = BCrypt.HashPassword(password);
    
    // Check if the hash of the entered login password, matches the stored hash.
    // The salt and the cost factor will be extracted from existingHashFromDb.
    bool isPasswordCorrect = BCrypt.Verify(password, existingHashFromDb);
    

    另一个不错的算法是PBKDF2,crackstation.net有一个不错的code example

    如果你对更详细的信息感兴趣,可以看看我关于safely storing passwords的教程。

    【讨论】:

      【解决方案2】:

      这个想法是加密或散列密码,但永远不要解密它。 IE。您以不可逆的方式转换密码。

      • 第一次输入密码时,您(一种方式)加密 密码并保存。
      • 当用户尝试登录时,输入的密码会再次加密并与存储的密码进行比较。

      这个answer中已经提供了一个代码示例:

      byte[] data = System.Text.Encoding.ASCII.GetBytes(inputString);
      data = new System.Security.Cryptography.SHA256Managed().ComputeHash(data);
      String hash = System.Text.Encoding.ASCII.GetString(data);
      

      您的程序将存储/比较 hash 值而不是普通密码。

      代码可以而且应该得到进一步的批准。攻击者可以创建加密密码的大型字典/彩虹表,并将它们用作密码破解的查找。这可以通过在要加密的密码中添加一些“salt”来防止。更多详情请看answer

      【讨论】:

      • 这段代码对哈希加盐了吗?!如果不是,它就不能真正用于密码。
      • @ThiefMaster 谢谢。在我的回答中推荐了“盐”,并添加了详细链接。
      • 不要为此使用SHA256Managed,使用真正的密码散列算法,如 PBKDF2 或 BCrypt。这些哈希在多次迭代(通常为 100 到 1000 次)中进行,以使其更难暴力破解哈希。