从密码c#中提取盐分
本文关键字:提取 密码 | 更新日期: 2023-09-27 18:09:15
我有一个函数来计算带盐的SHA256哈希。然后将盐附加到散列密码上并进行存储。执行此操作的函数如下所示:
public static string CalculateHash(string input)
{
var inputBuffer = new List<byte>(Encoding.Unicode.GetBytes(input));
var saltBytes = new byte[16];
using (var rnd = RandomNumberGenerator.Create())
{
rnd.GetBytes(saltBytes);
}
inputBuffer.AddRange(saltBytes);
byte[] hashedBytes;
using (var hasher = new SHA256Managed())
{
hashedBytes = hasher.ComputeHash(inputBuffer.ToArray());
}
var hash = BitConverter.ToString(hashedBytes).Replace("-", string.Empty);
var salt = BitConverter.ToString(saltBytes).Replace("-", string.Empty);
return string.Format("{0}:{1}", hash, salt);
}
它存储了一个长度为97个字符的字符串(包括':'),似乎工作得很好。当我把哈希拿回来的时候,我正在努力把盐从哈希上剥下来。我遇到的问题是将盐以字符串形式转换回包含原始字节的byte[16]
。我假设一旦我有了这16个原始字节,我就可以将它们附加到用户输入,并对密码进行散列以检查是否匹配。
我目前的尝试是在冒号分隔符处分割散列密码和盐,并使用GetBytes
函数。它是这样工作的:
public static bool ValidatePassword(string password, string hashWithSalt)
{
var split = hashWithSalt.Split(':');
var salt = split[1];
var saltBytes = GetBytes(salt);
}
private static byte[] GetBytes(string str)
{
var bytes = new byte[str.Length * sizeof(char)];
Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
但GetBytes
目前返回byte[64]
,这显然不是原来的字节格式。我该如何着手解决这个问题?
我自己想出了解决办法。只需要改变GetBytes
函数来处理十六进制转换。
private static byte[] GetBytes(string str)
{
return Enumerable.Range(0, str.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(str.Substring(x, 2), 16))
.ToArray();
}