【问题标题】:C# - Securely storing a password locallyC# - 在本地安全地存储密码
【发布时间】:2013-06-02 04:33:37
【问题描述】:

我正在创建一个 C# 应用程序,它将在 Kiosk 风格的环境中锁定功能(组合键、Windows 任务栏等)。其中一项要求是,某些人应该仍然能够使用组合键和密码破解应用程序。

应用程序本身已完全完成,但我还没有找到存储和检查密码的好方法。一切都应该存储在本地(不检查网络数据库或其他)。如何定义用于解锁我的应用程序的密码,同时使其灵活(无需重新编译应用程序即可更改密码)。我怎样才能以安全的方式做到这一点?

【问题讨论】:

  • 与其DIY,不如设置一个本地管理员账户?无论如何,您的应用不会阻止 Ctrl+Alt+Del。
  • 不,不会。但要求是一个人应该能够完全访问当前会话。很遗憾,我无法改变这一点。

标签: c# .net security passwords kiosk


【解决方案1】:

存储密码的安全哈希,它不需要是可逆的。

当有人输入密码时,您使用相同的算法对其进行哈希处理并检查它是否与哈希值匹配。

因为您从不存储实际密码,所以它是安全的。

我建议使用像 PBKDF2 这样的密钥拉伸算法。 .Net 使用 Rfc2898DeriveBytes 对此提供支持,或者您可以使用 System.Web.Helpers.Crypto

【讨论】:

    【解决方案2】:

    在配置文件中存储密码的标准方法是使用强哈希算法。阅读How to store passwords in Winforms application? 的答案,也可以阅读https://en.wikipedia.org/wiki/Cryptographic_hash_function 的wiki 文章

    【讨论】:

    【解决方案3】:

    我不得不不同意 Brian,因为到目前为止,在任何数据库中存储密码的标准方法是“加盐”(有关详细说明,请参阅 Wikipedia)密码具有随机生成的值并存储散列值以及“数据库”中的盐(见备注)。盐不是秘密,因此您可以将其存储为纯文本。每当用户输入您从文件中读取盐的密码时,将其应用于输入的密码,然后应用您选择的哈希算法。然后将结果与存储的哈希值进行比较。如果它们匹配,则对用户进行身份验证。对于一个好的(和有趣的:))解释为什么“只是”散列密码是不够的,请参阅:How NOT to store passwords! 有关 C# 中加盐和散列过程的教程实现,请参阅:C# Salting & Hashing Passwords

    你也可以在这里找到一个好方法:https://stackoverflow.com/a/12657970


    为了快速参考,伪代码中的过程:

    第一个密码存储:

    //get user input
    username = GetUserName
    password = GetPassword
    
    //generate random salt
    salt = GetRandomValue
    
    //combine password and salt and apply hash
    hashedPassword = Hash(password + salt)
    
    //store hash value and salt in database
    AddToDatabase(username, hashedPassword, salt)
    


    用户登录:

    //get user input
    username = GetUserName
    password = GetPassword
    
    //read salt from database
    salt = GetSaltFromDatabase(username)
    
    //combine password and salt and apply hash
    hashedPassword = Hash(password + salt)
    
    //compare hash to stored hash value
    correctHash = GetHashFromDatabase(username)
    if (hashedPassword == correctHash) then
        passwordIsCorrect = True
    else
        passwordIsCorrect = False
    end if
    


    备注:

    • 这假定您的用户名是唯一的,因为它们被用作“数据库”中的标识键。
    • “数据库”不必是任何类型的“真实”数据库,也可以是您的配置文件或纯文本文件。

    【讨论】:

      【解决方案4】:

      您可以将密钥和密码的哈希值存储在某处,例如某个本地文件中。当用户输入密钥和密码时,您会获得此值的哈希值并将其与文件中的哈希值进行比较。

      【讨论】:

        【解决方案5】:

        您需要密码的哈希值并使用哈希文本进行验证。添加盐可以使您的密码更安全。在 .Net 中,您可以使用 System.Security.Cryptography.RNGCryptoServiceProvider

        Here 是一篇关于如何存储密码的好文章,我在我的 Web 应用程序中使用了它。

        【讨论】:

          【解决方案6】:

          【讨论】:

          • 很好的链接,但答案不应该只是链接而已。
          • 有一篇完整的文章,比我在这里给出的任何简短解释都要好得多;-)
          • 也许可以,但链接会随着时间的推移而消失。一定要链接到更长的文章,但如果该链接发生变化,答案应该是完整的。
          猜你喜欢
          • 2017-03-23
          • 2015-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-23
          • 1970-01-01
          • 1970-01-01
          • 2022-11-11
          相关资源
          最近更新 更多