2010-03-19 85 views
3

我接管了以前的开发人员编写的系统。系统有管理员批准用户帐户,当他们这样做时,系统使用以下方法散列密码并将其保存到数据库。它将未加密的密码发送给用户。当用户登录时,系统使用完全相同的方法来散列用户输入的内容并将其与数据库值进行比较。当数据库条目与用户输入的数据不匹配时,我们遇到了几次问题。所以看起来该方法并不总是散列值相同。有谁知道这种哈希方法不可靠吗?如何使它可靠?谢谢。散列密码给出不同的结果

private string HashPassword(string password) 
    { 
     string hashedPassword = string.Empty; 

     // Convert plain text into a byte array. 
     byte[] plainTextBytes = Encoding.UTF8.GetBytes(password); 

     // Allocate array, which will hold plain text and salt. 
     byte[] plainTextWithSaltBytes = 
       new byte[plainTextBytes.Length + SALT.Length]; 

     // Copy plain text bytes into resulting array. 
     for(int i = 0; i < plainTextBytes.Length; i++) 
      plainTextWithSaltBytes[i] = plainTextBytes[i]; 

     // Append salt bytes to the resulting array. 
     for(int i = 0; i < SALT.Length; i++) 
      plainTextWithSaltBytes[plainTextBytes.Length + i] = SALT[i]; 

     // Because we support multiple hashing algorithms, we must define 
     // hash object as a common (abstract) base class. We will specify the 
     // actual hashing algorithm class later during object creation. 
     HashAlgorithm hash = new SHA256Managed(); 

     // Compute hash value of our plain text with appended salt. 
     byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes); 

     // Create array which will hold hash and original salt bytes. 
     byte[] hashWithSaltBytes = new byte[hashBytes.Length + 
              SALT.Length]; 
     // Copy hash bytes into resulting array. 
     for(int i = 0; i < hashBytes.Length; i++) 
      hashWithSaltBytes[i] = hashBytes[i]; 

     // Append salt bytes to the result. 
     for(int i = 0; i < SALT.Length; i++) 
      hashWithSaltBytes[hashBytes.Length + i] = SALT[i]; 

     // Convert result into a base64-encoded string. 
     hashedPassword = Convert.ToBase64String(hashWithSaltBytes); 

     return hashedPassword; 
    } 

回答

1

如果过程不使用任何随机决策(即,它是完全确定的),以及所使用的算法的实现是相同的(他们应该是 - SHA256应该作用完全到处都是一样的,Base64字符串也是一样),那么算法本身“不会散列相同的值”是非常不可能的。

如果你不能重现错误(意思是:找到某个值,当服务器散列时总是产生一个散列值,当客户端散列时总是产生一个散列值),你应该确保这些值是正确传输和接收的。也许客户端获得了非哈希密码?也许服务器正在接收来自客户端的损坏数据?也许服务器数据库本身的数据有某种改变? 确保每笔交易都经过验证,即用户无法收到损坏的密码。

4

这个函数做散列加盐。这是一个技术,以确保它产生不同的散列相同的密码,并使表查找更困难。

只有当具有相同的盐值时,散列才是相同的

有关此技术的详细信息,请参阅wikipedia http://en.wikipedia.org/wiki/Salt_%28cryptography%29

报价http://msdn.microsoft.com/en-us/magazine/cc164107.aspx

减缓攻击,使用的盐。 盐是在对它们进行哈希处理之前对密码 进行调整的一种方式,使得攻击者的预计算字典 无用。这是如何完成的。 无论何时向 数据库添加条目,您都会计算一个随机的 字符串以用作盐。 当你想计算Alice的密码的散列值时,你可以查询Alice的帐户的 值,在密码前加上 ,并将它们一起散列 。生成的数据库看起来 这样的:

<users> 
    <user name='Alice' salt='Tu72*&' password='6DB80AE7...'/> 
    <user name='Bob' salt='N5sb#X' password='096B1085...'/> 
    <user name='Fred' salt='q-V3bi' password='9118812E...'/> 
</users> 

注意,现在还没有办法告诉 鲍勃和弗雷德都使用相同的密码 。请注意,盐本身并不是秘密 。