密码哈希结果不一致的问题

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;
    }
2个回答

4

这个函数使用盐值(salt)进行哈希。这是一种技术,可以确保对于相同的密码产生不同的哈希值,并使表查找更加困难。

只有当您具有相同的盐值时,哈希才相同。

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

引用http://msdn.microsoft.com/en-us/magazine/cc164107.aspx

To slow down the attack, use salt. Salt is a way to season the passwords before hashing them, making the attacker's precomputed dictionary useless. Here's how it's done. Whenever you add an entry to the database, you calculate a random string of digits to be used as salt. When you want to calculate the hash of Alice's password, you look up the salt value for Alice's account, prepend it to the password, and hash them together. The resulting database looks like this:

<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>

Note that now there is no way to tell that Bob and Fred are using the same password. Note that the salt itself isn't a secret.


1

如果该过程不使用任何随机决策(即完全确定性),并且所使用的算法实现相同(应该如此 - SHA256应在任何地方都表现完全相同,Base64字符串也是如此),那么算法本身“未对值进行哈希”是非常不可能的。

如果您无法重现错误(意思是:找到某个值,当在服务器上哈希时产生一个哈希值,而在客户端哈希时产生另一个哈希值),则应确保正确传输和接收值。也许客户端收到了未经哈希处理的密码混乱?也许服务器从客户端接收到了损坏的数据?也许服务器数据库中的数据已经发生了变化?请确保每个交易都经过验证,即用户不能接收到损坏的密码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接