从密码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],这显然不是原来的字节格式。我该如何着手解决这个问题?

从密码c#中提取盐分

我自己想出了解决办法。只需要改变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();
}