我刚刚浏览了 DavidHayden 的一篇关于Hashing User Passwords的文章。
真的,我无法得到他想要达到的目标。
这是他的代码:
private static string CreateSalt(int size) { //Generate a cryptographic random number. RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] buff = new byte[size]; rng.GetBytes(buff); // Return a Base64 string representation of the random number. return Convert.ToBase64String(buff); } private static string CreatePasswordHash(string pwd, string salt) { string saltAndPwd = String.Concat(pwd, salt); string hashedPwd = FormsAuthentication.HashPasswordForStoringInConfigFile( saltAndPwd, "sha1"); return hashedPwd; }
是否有任何其他 C# 方法用于散列密码并添加盐?
实际上,这有点奇怪,使用字符串转换 - 成员资格提供程序将它们放入配置文件中。哈希和盐是二进制 blob,除非要将它们放入文本文件,否则无需将它们转换为字符串。
在我的《开始 ASP.NET 安全性》一书中,(哦,终于有了一个拉皮条的借口)我做了以下事情
static byte[] GenerateSaltedHash(byte[] plainText, byte[] salt) { HashAlgorithm algorithm = new SHA256Managed(); byte[] plainTextWithSaltBytes = new byte[plainText.Length + salt.Length]; for (int i = 0; i < plainText.Length; i++) { plainTextWithSaltBytes[i] = plainText[i]; } for (int i = 0; i < salt.Length; i++) { plainTextWithSaltBytes[plainText.Length + i] = salt[i]; } return algorithm.ComputeHash(plainTextWithSaltBytes); }
盐的产生就是问题中的例子。您可以使用 将文本转换为字节数组Encoding.UTF8.GetBytes(string)。如果您必须将哈希转换为其字符串表示形式,您可以使用Convert.ToBase64String并将Convert.FromBase64String其转换回来。
Encoding.UTF8.GetBytes(string)
Convert.ToBase64String
Convert.FromBase64String
您应该注意,您不能在字节数组上使用相等运算符,它会检查引用,因此您应该简单地遍历两个数组,检查每个字节
public static bool CompareByteArrays(byte[] array1, byte[] array2) { if (array1.Length != array2.Length) { return false; } for (int i = 0; i < array1.Length; i++) { if (array1[i] != array2[i]) { return false; } } return true; }
始终 为每个密码使用新的盐。盐不必保密,可以与散列本身一起存储。