我使用此函数来计算哈希值:
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)
但现在我有几个问题:
哈希函数应该为任何类型的字符串创建固定输出长度(无论我的输入长度是4还是10000,输出始终具有固定大小),不是吗?但是当我的输入长度改变时,输出长度也会改变!我猜我的哈希函数不起作用。
如果我想将结果保存在数据库中,我的哈希值字段类型应该是什么?
Web应用程序中通常使用哪种哈希函数?
谢谢。
当前,您只是返回所有字节的十进制表示形式,它们串联在一起。因此{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)
(请注意,我已经声明局部变量-你似乎是使用领域为data和result,这是一个坏主意-调用这些方法不会影响实例的状态,IMO)。
或者,您可以返回a byte[]并将其作为blob直接存储在数据库中。不过,使用base64或hex可能更简单-以这种方式检查数据更容易,并且坦率地说更容易查询。字符串更易于处理:)
关于应该使用哪种哈希-除非必须,否则我可能不会使用SHA-1或MD5。我默认使用SHA-256,尽管它取决于您要执行的操作。例如,如果这是对密码进行哈希处理,则您可能需要某种描述的HMAC-或更好的是,不要自己滚动,使用现成的身份验证程序包。