хэширующий пароль дает разные результаты - PullRequest
3 голосов
/ 19 марта 2010

Я забираю систему, написанную предыдущим разработчиком. В системе администратор утверждает учетную запись пользователя, и когда они это делают, система использует следующий метод для хеширования пароля и его сохранения в базе данных. Он отправляет не хэшированный пароль пользователю. Когда пользователь входит в систему, использует тот же метод для хеширования введенного пользователем и сравнивает его со значением базы данных. Мы сталкивались пару раз, когда запись в базе данных не совпадает с записью пользователя, если они должны. Таким образом, похоже, что метод не всегда хэширует значение одинаково. Кто-нибудь знает, если этот метод хеширования не надежен и как сделать его надежным? Спасибо.

    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 голосов
/ 17 мая 2010

Эта функция делает хэширование с солью . Это метод, который гарантирует, что он даст другой хеш для одного и того же пароля и сделает поиск в таблице намного сложнее.

Хеш такой же , только если у вас такое же значение соли.

см. Википедию http://en.wikipedia.org/wiki/Salt_%28cryptography%29 для подробностей об этой технике.

Цитата http://msdn.microsoft.com/en-us/magazine/cc164107.aspx:

Чтобы замедлить атаку, используйте соль. Соль - это способ приправить пароли прежде чем хешировать их, делая предварительно вычисленный словарь злоумышленника бесполезный. Вот как это делается. Всякий раз, когда вы добавляете запись в базы данных, вы рассчитываете случайный строка цифр для использования в качестве соли. Когда вы хотите вычислить хеш Пароль Алисы, вы посмотрите соль значение для счета Алисы, добавьте его к паролю, и хэш их все вместе. Полученная база данных выглядит как это:

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

Обратите внимание, что теперь нет никакого способа сказать что Боб и Фред используют одно и то же пароль. Обратите внимание, что сама соль не секрет.

1 голос
/ 19 марта 2010

Если в процедуре не используется случайное принятие решений (то есть, оно полностью детерминировано), и реализации используемых алгоритмов одинаковы (и они должны быть - SHA256 должен действовать везде одинаково, и то же самое относится и к строкам Base64), поэтому очень маловероятно, что сам алгоритм «не хэширует значение одинаково».

Если вы не можете воспроизвести ошибку (имеется в виду: найти какое-то значение, которое всегда создает один хеш при хешировании на сервере, а другой - при хешировании клиентом), вы должны убедиться, что значения переданы и получены правильно. Может быть, клиент получил взломанный пароль? Может быть, сервер получает поврежденные данные от клиента? может данные в самой базе данных сервера как-то изменились? Убедитесь, что каждая транзакция подтверждена, то есть пользователь не может получить поврежденный пароль.

...