C# - 在本地安全地存储密码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16957492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# - Securely storing a password locally
提问by romatthe
I'm creating a C# application that will lock out functionality (key combinations, windows task bar, etc.) in a Kiosk-style environment. One of the requirements is that some people should still be able to break out of the application using a key combination and a password.
我正在创建一个 C# 应用程序,它将在 Kiosk 风格的环境中锁定功能(组合键、Windows 任务栏等)。其中一项要求是,某些人仍应能够使用组合键和密码退出应用程序。
The application itself is completely done, but I have not found a good way to store and check against a password. Everything should be stored locally (there is not check against a network database or whatever). How can I define a password for unlocking my application while also making this flexible (the ability to change the password without recompiling the application). How can I accomplish this in a secure way?
应用程序本身已完全完成,但我还没有找到存储和检查密码的好方法。一切都应该存储在本地(不检查网络数据库或其他任何东西)。我如何定义用于解锁我的应用程序的密码,同时使其灵活(无需重新编译应用程序即可更改密码的能力)。如何以安全的方式完成此操作?
采纳答案by Brian O''Byrne
The standard method for storing a password in a configuration file is to use a strong hash algorithm. Read the answer at How to store passwords in Winforms application?and maybe the wiki article at https://en.wikipedia.org/wiki/Cryptographic_hash_function
在配置文件中存储密码的标准方法是使用强哈希算法。阅读如何在 Winforms 应用程序中存储密码?也许是https://en.wikipedia.org/wiki/Cryptographic_hash_function 上的维基文章
回答by Oscar
Is relatively easy using ProtectSection()and UnprotectSection()methods from SectionInformationclass. See this article:
相对容易使用ProtectSection()和UnprotectSection()来自SectionInformation类的方法。看这篇文章:
http://www.davidgiard.com/2012/06/05/EncryptingAndDecryptingApplicationConfigSections.aspx
http://www.davidgiard.com/2012/06/05/EncryptingAndDecryptingApplicationConfigSections.aspx
http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.protectsection.aspx
http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.protectsection.aspx
回答by rpeshkov
You can store a hash of your key and a password somewhere, for example in some local file. When person input key and password, you get hashes for this values and compare it with hashes in your file.
您可以将密钥和密码的散列存储在某处,例如在某个本地文件中。当人们输入密钥和密码时,您将获得此值的哈希值并将其与文件中的哈希值进行比较。
回答by Keith
Store a secure hash of the password, it doesn't need to be reversible.
存储密码的安全散列,它不需要是可逆的。
When someone enters a password you hash that by the same algorithm and check it matches the hash.
当有人输入密码时,您通过相同的算法对其进行哈希处理并检查它是否与哈希匹配。
Because you never store the actual password it's secure.
因为您从不存储实际密码,所以它是安全的。
I recommend using a key stretching algorithm like PBKDF2. .Net has support for this using Rfc2898DeriveBytesor you can use System.Web.Helpers.Crypto.
我建议使用像 PBKDF2 这样的密钥拉伸算法。.Net 支持此使用,Rfc2898DeriveBytes或者您可以使用System.Web.Helpers.Crypto.
回答by Chris Li
You need a hash of the password and validate using the hashed text. Adding a salt can make your password more secure. In .Net, you can use System.Security.Cryptography.RNGCryptoServiceProvider.
您需要密码的散列并使用散列文本进行验证。添加盐可以使您的密码更安全。在 .Net 中,您可以使用System.Security.Cryptography.RNGCryptoServiceProvider。
Hereis a good article talking about how to store your passwords and I use its way in my web application.
这是一篇关于如何存储密码的好文章,我在我的 Web 应用程序中使用了它。
回答by Marcus Mangelsdorf
I have to disagree with Brian, because as of now the standard method for storing passwords in any database is to "salt" (see Wikipediafor a detailed explanation) the password with a randomly generated value and store the hashed value and the salt in your "database" (see remarks). The salt is not a secret so you can store it in plain text. Whenever the user enters the password you read the salt from your file, apply it to the entered password and then apply your chosen hash algorithm. Then you compare the results with your stored hash. If they match, the user is authenticated. For a good (and entertaining :)) explanation why "just" hashing the password isn't enough, see: How NOT to store passwords!For a tutorial implementation of the salting and hashing process in C# see: C# Salting & Hashing Passwords
我不得不不同意布赖恩的观点,因为到目前为止,在任何数据库中存储密码的标准方法是使用随机生成的值“加盐”(参见维基百科的详细解释)密码,并将散列值和加盐值存储在您的数据库中“数据库”(见备注)。盐不是秘密,因此您可以将其以纯文本形式存储。每当用户输入密码时,您就会从文件中读取 salt,将其应用于输入的密码,然后应用您选择的哈希算法。然后将结果与存储的哈希值进行比较。如果它们匹配,则用户通过身份验证。对于一个好的(和有趣的:))解释为什么“只是”散列密码是不够的,请参阅:如何不存储密码!C# 加盐和散列密码
You can also find a good way to do this here: https://stackoverflow.com/a/12657970
你也可以在这里找到一个很好的方法:https: //stackoverflow.com/a/12657970
For a quick reference, the process in pseudocode:
为了快速参考,伪代码中的过程:
First password storage:
第一个密码存储:
//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)
User login:
用户登录:
//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
Remarks:
评论:
- This assumes that your usernames are unique as they are used as identifying key in your "database".
- The "database" doesn't have to be any kind of "real" database, it can also be your configuration file or a plain text file.
- 这假设您的用户名是唯一的,因为它们被用作“数据库”中的识别键。
- “数据库”不必是任何类型的“真实”数据库,它也可以是您的配置文件或纯文本文件。

