【发布时间】:2012-06-30 00:15:47
【问题描述】:
我有一个带有登录表单的 WinForms 应用程序,我想将加密的用户名和密码存储在 SQLite 数据库中。看到可以使用salt和hash,但是不知道代码里的密码怎么加密,认证的时候对比一下。
有什么帮助吗?
【问题讨论】:
-
如果您使用加密来保护密码,那么您做错了。
标签: c# winforms saltedhash
我有一个带有登录表单的 WinForms 应用程序,我想将加密的用户名和密码存储在 SQLite 数据库中。看到可以使用salt和hash,但是不知道代码里的密码怎么加密,认证的时候对比一下。
有什么帮助吗?
【问题讨论】:
标签: c# winforms saltedhash
您将需要获取用户名和密码(来自屏蔽文本框的密码,最好使用第二个框进行确认)对其进行加盐,并从密码创建哈希,然后插入明文用户名和加盐哈希数据库中的密码。然后,您可以通过将数据库存储的版本与用户输入的加盐(相同的盐!)哈希值进行比较来验证用户密码。
请注意,每个用户都应该有自己的盐,您在创建帐户时会为该用户随机生成这些盐。 (这比黑客可以发现的全局盐值更安全。
看看this article。它几乎涵盖了所有基础,但不要使用文章中推荐的 SHA-1。您需要一个计算量很大的慢速散列函数,例如 BCrypt 或 PBKDF2(包含在 .NET 中)。见"What makes a good hash function for passwords"。 (感谢@CodeInChaos 指出这一点)。
您可以在 System.Security.Cryptography 中使用Rfc2898DeriveBytes 来创建密码的加盐哈希,PBKDF2 样式。
byte[] salt = Guid.NewGuid().ToByteArray[];
Rfc2898DeriveBytes saltedHash = new Rfc2898DeriveBytes("P@$$w0rd", salt, 1000);
一个好的经验法则是迭代次数应该使散列操作花费大约一秒钟。
【讨论】:
您需要将哈希密码和盐存储在数据库中。为每个用户使用随机盐(GUID 应该没问题) 你可以用类似的东西来散列你的密码:
记得添加using System.Security.Cryptography;命名空间。
public static string ComputeHash(string passwordPlainText, string saltString)
{
// Convert plain text into a byte array.
byte[] saltBytes = Encoding.UTF8.GetBytes(saltString);
// Convert plain text into a byte array.
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
// Allocate array, which will hold plain text and salt.
byte[] plainTextWithSaltBytes =
new byte[plainTextBytes.Length + saltBytes.Length];
// Copy plain text bytes into resulting array.
for (int i = 0; i < plainTextBytes.Length; i++)
plainTextWithSaltBytes[i] = plainTextBytes[i];
// Append salt bytes to the resulting array.
for (int i = 0; i < saltBytes.Length; i++)
plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];
// Because we support multiple hashing algorithms, we must define
// hash object as a common (abstract) base class. We will specify the
// actual hashing algorithm class later during object creation.
HashAlgorithm hash;
hash = new SHA256Managed();
// Compute hash value of our plain text with appended salt.
byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);
// Create array which will hold hash and original salt bytes.
byte[] hashWithSaltBytes = new byte[hashBytes.Length +
saltBytes.Length];
// Copy hash bytes into resulting array.
for (int i = 0; i < hashBytes.Length; i++)
hashWithSaltBytes[i] = hashBytes[i];
// Append salt bytes to the result.
for (int i = 0; i < saltBytes.Length; i++)
hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];
// Convert result into a base64-encoded string.
string hashValue = Convert.ToBase64String(hashWithSaltBytes);
// Return the result.
return hashValue;
}
您可以将SHA256Managed 更改为任何其他受支持的哈希算法。
更新:我认为您需要先了解这个概念。我会试着解释一下:
在登录之前,您需要在数据库中创建用户。要创建它们,您需要用户名和密码。
Guid.NewGuid().ToString();。string ComputeHash(string passwordPlainText, string saltString)函数来完成。【讨论】: