Я хотел знать, может ли процесс хеширования хеша помочь остановить атаки на него (грубая сила, я думаю) при использовании с солью. Итак, мой код:
function hash_password($password, $salt, $site_key) { $hash = hash('sha512', $password . $salt . $site_key); for ($i=0; $i<1000; $i++) { $hash = hash($hash); } return $hash; }
Из того, что я могу решить, мой код будет безопасным, потому что он останавливает атаки радужного стола, используя соль, и останавливает атаки грубой силы, итерируя хэш.
Может ли эта итерация сделать атаки грубой силы намного сложнее? И если да, то насколько это повлияет на производительность? (как долго это займет хэш в 1000 раз, я слышал, что кто-то сказал, что вы должны перебирать хеш, пока он не займет 200 мс)
Выполняет ли это эмулирование поведения алгоритма, такого как bcrypt?
Да, это так, по простой причине. Хэши были построены для скорости, а не для обеспечения безопасности (поскольку это часто используется для расчета контрольных сумм для больших файлов). Таким образом, компьютер с сильным процессором (или хакером, использующим графический процессор) может переборщить ваш код, скажем, 1 миллиард хэшей в секунду.
Если вы убедитесь, что ваш алгоритм хеширования медленнее (итерацией по нему тысячу раз), тот же компьютер сможет выполнить этот алгоритм только 1 миллион раз в секунду, а не сто. Так что если бы 60-дневный взломщик взломал пароль с грубой силой, то теперь потребовалось бы 60 000 часов, что составляет почти 7 лет 🙂
Однако ваш код не реализует его правильно, вы повторяете одно и то же действие снова и снова, где вы должны использовать хэш, который вы получили в предыдущем хеше, плюс добавить некоторые символы безопасности (как правило, индекс итерации).
while (i < 1000) { hash(somehash) } //wrong while (i < 1000) { hash = hash(hash . i) } //correct.
У PHP уже есть эта функциональность, встроенная для вас! Используя crypt()
в сочетании с CRYPT_BLOWFISH
(aka bcrypt
), вы можете ввести свой пароль и соль в функцию и получить готовый хеш после итераций и всего остального. Для получения дополнительной информации см. Этот вопрос.
Код, который у вас там, просто повторяет одно и то же снова и снова. Если вы посмотрите на $hash
после первой итерации и после последней итерации, вы увидите, что они одинаковы.
Вот почему мы просто используем такие вещи, как bcrypt. Если вы попытаетесь реализовать его самостоятельно, вы, скорее всего, сделаете это неправильно 🙂