我只是在阅读DavidHayden的有关散列用户密码的文章之一。
真的我无法理解他想要达到的目标。
这是他的代码:
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,除非要将它们放入文本文件,否则无需将它们转换为字符串。
在我的《Beginning ASP.NET Security》一书中(最后,借口是这本书的借口),我执行以下操作
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; }
始终 为每个密码使用新的盐。盐不必保密,可以与哈希表本身一起存储。