Много хеш-итераций: добавлять соль каждый раз? - PullRequest
36 голосов
/ 24 августа 2010

Я долгое время использовал несоленый md5 / sha1, но так как этот метод не совсем безопасен (и со временем становится все менее безопасным), я решил переключиться на соленый sha512.Кроме того, я хочу замедлить генерацию хэша, используя много итераций (например, 100).

Мой вопрос заключается в том, должен ли я добавлять соль на каждую итерацию или только один раз в начале.Вот два возможных кода:

Добавить каждый раз:

// some nice big salt
$salt = hash($algorithm, $salt);

// apply $algorithm $runs times for slowdown
while ($runs--) {
    $string = hash($algorithm, $string . $salt, $raw);
}

return $string;

Добавить один раз:

// add some nice big salt
$string .= hash($algorithm, $salt);

// apply $algorithm $runs times for slowdown
while ($runs--) {
    $string = hash($algorithm, $string, $raw);
}

return $string;

Сначала я хотел использовать вторую версию (добавить один раз), но потом нашел несколько сценариев, добавляющих соль каждый раз.

Итак, мне интересно, добавляет ли это каждый раз добавление силы в хэш.Например, возможно ли, что злоумышленник нашел какой-нибудь умный способ создать функцию 100хSha512, которая была бы намного быстрее, чем простое выполнение sha512 в 100 раз?

Ответы [ 5 ]

51 голосов
/ 24 августа 2010

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

Идля записи, я поддерживаю хеширование несколько раз.

Хеш, который генерирует 500 мс, не слишком медленный для вашего сервера (учитывая, что генерация хешей обычно не выполняется подавляющим большинством запросов).Однако такой длительный хеш значительно увеличит время, необходимое для создания радужной таблицы ...

Да, он предоставляет уязвимость DOS, но также предотвращает атаки методом подбора (или, по крайней мере,они непомерно медленные).Это абсолютно компромисс, но некоторые преимущества превосходят риски ...

Ссылка (больше похожая на обзор) на весь процесс: Усиление ключа

Что касается вырождающихся столкновений, единственный источник, который я смог найти до сих пор, это это обсуждение ...

И еще несколько обсуждений по теме:

  1. Предложение HEKS
  2. Блог SecurityFocus о хешировании
  3. Статья об алгоритмах хеширования паролей Oracle

И еще несколько ссылок:

  1. PBKDF2 на WikiPedia
  2. PBKDF2 Standard
  3. Электронная почтаприменимая тема
  4. Просто хеширование далеко не достаточно Сообщение в блоге

Есть множество результатов.Если вы хотите больше, Google hash stretching ... Там есть тонна хорошей информации ...

6 голосов
/ 24 августа 2010

Помимо многократного повторного хеширования, я бы использовал разные соли для каждого пароля / пользователя. Хотя я думаю, что 5000 итераций - это слишком много, попробуйте меньшее число. Здесь есть компромисс; вам придется настроить его в соответствии с вашими потребностями и оборудованием.

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

Как всегда, вот рекомендуемое прочтение для этого: Просто хеширования недостаточно

РЕДАКТИРОВАТЬ: итеративное хеширование - совершенно правильная тактика . Есть компромиссы, но все есть. Если вас беспокоит время вычислений, почему бы просто не сохранить незашифрованный пароль?

3 голосов
/ 29 октября 2010

Пожалуйста, пожалуйста, не бросайте свой собственный крипто. Для этого и нужны такие библиотеки, как OpenSSL. Вот несколько хороших примеров того, как вы могли бы использовать его для создания соленых хешей.

Соленые хэши в OpenSSL

0 голосов
/ 28 октября 2010

Я предпочитаю идти с двойным sha1 с двумя разными солями и не допускать, чтобы DoS постепенно задерживал ответ (с помощью простого сна) для каждой проверки неверного пароля.

0 голосов
/ 25 августа 2010

Причина итеративного хеширования - сделать процесс как можно медленнее. Так что вы можете сделать еще лучше: используйте разные соли для каждой итерации. Это можно сделать, зашифровывая исходные данные снова и снова на каждой итерации с помощью фиксированного ключа и XOR с использованием значения соли.

...