C# – 在本地安全地存储密码

我正在创建一个C#应用程序,它将在Kiosk风格的环境中锁定function(组合键,窗口任务栏等)。 其中一个要求是,某些人仍然可以使用密钥组合和密码来突破应用程序。

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

在配置文件中存储密码的标准方法是使用强哈希算法。 阅读如何在Winforms应用程序中存储密码的答案? 也许是https://en.wikipedia.org/wiki/Cryptographic_hash_function上的wiki文章

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

当有人输入密码时,您可以使用相同的算法对其进行散列并检查它是否与散列匹配。

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

我建议使用像PBKDF2这样的按键拉伸算法。 .Net使用Rfc2898DeriveBytes支持此Rfc2898DeriveBytes或者您可以使用System.Web.Helpers.Crypto

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

我不得不反对Brian,因为截至目前,在任何数据库中存储密码的标准方法是“盐”(参见维基百科的详细解释)密码,其中包含随机生成的值,并将散列值和盐存储在您的密码中“数据库”(见备注)。 盐不是秘密,所以你可以用纯文本存储它。 每当用户输入密码时,您从文件中读取盐,将其应用于输入的密码,然后应用您选择的哈希算法。 然后将结果与存储的哈希值进行比较。 如果匹配,则对用户进行身份validation。 为了一个好的(和有趣的:))解释为什么“只是”哈希密码是不够的,请参阅: 如何不存储密码! 有关C#中salting和散列过程的教程实现,请参阅: 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 

备注:

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

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

这是一篇很好的文章,讨论如何存储您的密码,我在我的Web应用程序中使用它的方式。