Я использовал unsalted 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;
Сначала я хотел использовать вторую версию (добавить один раз), но затем нашел некоторые скрипты, добавляющие соль каждый раз.
Итак, я задаюсь вопросом, добавляет ли он каждый раз добавление некоторой силы в хеш. Например, возможно ли, что злоумышленник нашел какой-то умный способ создать функцию 100timesSha512, которая была намного быстрее, чем просто выполнить sha512 100 раз?
Короче: Да. Пойдите с первым примером … Хеш-функция может потерять энтропию, если она сама возвращается без добавления исходных данных (теперь я не могу найти ссылку, я буду продолжать искать).
И для записи, я поддерживаю хеширование несколько раз.
Хэш, который занимает 500 мс для генерации, не слишком медленный для вашего сервера (учитывая, что генерация хэшей обычно не выполняется подавляющим большинством запросов). Однако хэш, который длится так долго, значительно увеличит время, необходимое для создания радужного стола …
Да, это подвергает уязвимость DOS, но также предотвращает атаки грубой силы (или, по крайней мере, делает их чрезмерно медленными). Существует абсолютно компромисс, но некоторые выгоды превышают риски …
Ссылка (больше похоже на обзор) на весь процесс: Укрепление ключа
Что касается вырождающихся столкновений, единственным источником, который я мог бы найти до сих пор, является это обсуждение …
И еще несколько дискуссий по теме:
И еще несколько ссылок:
Есть много результатов. Если вы хотите больше, Google hash stretching
… Там тонны хорошая информация там …
В дополнение к повторному хешированию его несколько раз, я использовал бы другую соль для каждого пароля / пользователя. Хотя я думаю, что 5000 итераций слишком много, попробуйте меньшее число. Здесь есть компромисс; вам придется настроить его в соответствии с вашими потребностями и оборудованием.
С разными солями для каждого пароля злоумышленник будет принудительно принудительно выполнять каждый отдельный пароль, а не строить радужный стол, что значительно увеличивает рабочую нагрузку.
Как всегда, здесь рекомендуется прочитать для этого: просто хэширование далеко не достаточно
EDIT: Итеративное хеширование – вполне эффективная тактика . Есть компромиссы, но у них все есть. Если вы беспокоитесь о времени вычислений, почему бы просто не хранить пароль открытого текста?
Пожалуйста, пожалуйста, не руляйте свой собственный крипто. Для этого нужны библиотеки OpenSSL. Вот несколько хороших примеров того, как вы будете использовать его для изготовления соленых хешей.
Соленые хеши в OpenSSL
Причина итеративного хеширования – сделать процесс как можно медленнее. Таким образом, вы можете сделать еще лучше: используйте разные соли для каждой итерации. Это можно сделать, зашифровав исходные данные снова и снова на каждой итерации с помощью фиксированного ключа и XORing со значением соли.
Я предпочитаю идти с двойным sha1 с двумя разными солями и предотвращать отсрочку ответа DoS поэтапно (простым проглатыванием) для каждой неверной проверки пароля.