将哈希值保存在数据库中

Dav*_*vid 0 c# hash

我使用此函数来计算哈希值:

public string GetSHA512(string input)
{
    byte[] data, result;
    StringBuilder hash = new StringBuilder();

    data = Encoding.UTF8.GetBytes(input);
    using (SHA512 shaM = new SHA512Managed())
    {
        result = shaM.ComputeHash(data);
    }

    for (int i = 0; i < result.Length; i++)
    {
        hash.Append(result[i].ToString());
    }

    return hash.ToString();
}

public string GetSHA256(string input)
{
    byte[] data, result;
    StringBuilder hash = new StringBuilder();

    data = Encoding.UTF8.GetBytes(input);
    using (SHA256 shaM = new SHA256Managed())
    {
        result = shaM.ComputeHash(data);
    }

    for (int i = 0; i < result.Length; i++)
    {
        hash.Append(result[i].ToString());
    }

    return hash.ToString();
}

public string GetSHA1(string input)
{
    byte[] data, result;
    StringBuilder hash = new StringBuilder();

    data = Encoding.UTF8.GetBytes(input);
    using (SHA1 shaM = new SHA1Managed())
    {
        result = shaM.ComputeHash(data);
    }

    for (int i = 0; i < result.Length; i++)
    {
        hash.Append(result[i].ToString());
    }

    return hash.ToString();
}

public string GetMD5(string input)
{
    byte[] data, result;
    StringBuilder hash = new StringBuilder();

    data = Encoding.UTF8.GetBytes(input);
    using (MD5 shaM = new MD5CryptoServiceProvider())
    {
        result = shaM.ComputeHash(data);
    }

    for (int i = 0; i < result.Length; i++)
    {
        hash.Append(result[i].ToString());
    }

    return hash.ToString();
}
Run Code Online (Sandbox Code Playgroud)

但现在我有几个问题:

  1. 哈希函数应该为任何类型的字符串创建固定输出长度(无论我的输入长度是4还是10000,输出始终具有固定大小),不是吗?但是当我的输入长度改变时,输出长度也会改变!我猜我的哈希函数不起作用。

  2. 如果我想将结果保存在数据库中,我的哈希值字段类型应该是什么?

  3. Web应用程序中通常使用哪种哈希函数?

谢谢。

Jon*_*eet 5

当前,您只是返回所有字节的十进制表示形式,它们串联在一起。因此{0,0,0}最终以“ 000”结尾,而{123,123,123}最终以“ 123123123”结尾。因此,是的,这两个哈希将为任何输入提供相同的输出大小(SHA-1将提供20个字节; MD5将提供16个字节),但是您的字符串表示形式当前长度有所不同。

我建议使用十六进制表示形式或base64-特别是base64需要较少的工作:

public string GetSHA1(string input)
{
    byte[] data = Encoding.UTF8.GetBytes(input);
    using (SHA512 shaM = new SHA512Managed())
    {
        byte[] result = shaM.ComputeHash(data);
        return Convert.ToBase64String(result);
    }
}
Run Code Online (Sandbox Code Playgroud)

十六进制的优点是它是表示哈希的更常见的方式。(Base64通常用于传输任意二进制数据,例如图像。)对于十六进制,可以使用:

return BitConverter.ToString(result).Replace("-", "");
Run Code Online (Sandbox Code Playgroud)

(请注意,我已经声明局部变量-你似乎是使用领域dataresult,这是一个坏主意-调用这些方法不会影响实例的状态,IMO)。

或者,您可以返回a byte[]并将其作为blob直接存储在数据库中。不过,使用base64或hex可能更简单-以这种方式检查数据更容易,并且坦率地说更容易查询。字符串更易于处理:)

关于应该使用哪种哈希-除非必须,否则我可能不会使用SHA-1或MD5。我默认使用SHA-256,尽管它取决于您要执行的操作。例如,如果这是对密码进行哈希处理,则您可能需要某种描述的HMAC-或更好的是,不要自己滚动,使用现成的身份验证程序包。