2015-06-17 141 views
0

我用这个功能来计算哈希值的数据库:保存哈希值

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(); 
} 

,但现在我有几个问题:

  1. 散列函数都应该建立固定输出长度对于任何类型的字符串(不管我的输入长度是4还是10000,输出总是有固定大小)不是吗?但是当我的输入长度改变时输出长度也改变了!我想我的散列函数不起作用。

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

  3. 哪一个散列函数通常用在web应用程序中?

谢谢。

回答

2

目前你只是返回十进制所有字节的表示,串联在一起。因此{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); 
    } 
} 

六角有被代表散列的更常见的方法的优点。 (Base64是更通常用于传输任意的二进制数据,如图像)为十六进制,你可以使用:

return BitConverter.ToString(result).Replace("-", ""); 

(请注意,我宣布当地变量 - 你似乎是使用领域对于dataresult,这是一个坏主意 - 调用这些方法不会影响实例的状态,IMO)

或者,你可以只返回一个byte[]和商店,直接在数据库中的一个blob。使用base64或hex可能更简单 - 以这种方式检查数据更容易,并且坦率地说更容易查询。字符串只是简单的处理:)

在你应该使用哪一个哈希值 - 我可能不会使用SHA-1或MD5,除非我必须;我会默认使用SHA-256,但这取决于你想要做什么。例如,如果这是哈希密码例如,您可能需要一些HMAC描述 - 或者更好的是,不要推出自己的,并使用现成的认证包。

2
  1. 每个哈希算法(md5/sha1/etc)都有自己的固定大小;
  2. 不要将输出散列转换为字符串,将其保存为byte []。
  3. 为了存储哈希,创建你的数据库BLOB列,并使用SqlParameter的,将其插入正确
1

通常的做法是将哈希码的字节数组转换为base64编码,用ToBase64String( ) 这也是密码的存储方式。 base64编码是一个固定长度的字符串,给定固定数量的字节。每个3字节需要4个字符,加上一些填充