Использование соли и более стойких алгоритмов хеширование значительно увеличивают надёжность, однако рассчёт даже длинных хешей — не очень сложная задача для современных систем, особенно с тех пор как для рассчётов стали привлекать GPU. Поэтому для увеличения надёжности шифрования паролей следует использовать такой алгоритм, который будет работать настолько медленно, что рассчёт радужных таблиц и атаки методом перебора станут абсолютно неэффективными. Это делает небезызвестная функция bcrypt. Для необратимого шифрования она использует алгоритм blowfish с множеством итераций, и работает очень медленно. Путём изменения количества итераций можно регулировать время, затрачиваемое на шифрования пароля, и найти такую «золотую середину», когда шифрование одного пароля будет достаточно быстрым, а подбор его станет бессмысленным.
В PHP есть встроенная функция crypt(), являющаяся реализацией bcrypt. С версиях PHP 5.3 и выше функция crypt() имеет встроенную реализацию алгоритмов шифрования и больше не зависит от поддержки этих алгоритмов операционной системой, чем и следует воспользоваться. Эта функция поддерживает различные алгоритмы, от DES до SHA-512, и выбирает алгоритм в зависимости от того, какая соль задаётся в качестве её параметра.
Ниже я хочу предложить простейший, состоящий из одной строчки генератор соли. Будучи скормленной функции crypt() данная соль заставит её использовать blowfish с 10 в квадрате итерациями. Это задаётся идентификатором $2a$ (использовать bcrypt), и идущим затем количеством итераций, которые задаются как логарифм по основанию 2 (в данном случае это 210, то есть 1024 итераций. Увеличение параметра на единицу удваивает количество итераций, и следовательно время рассчёта функции.
// Генерируем соль $salt = '$2a$10$'.substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(),mt_rand()))), 0, 22) . '$'; // Шифруем пароль с применением данной соли $hashed_password = crypt($password, $salt);
Соль будет длиной 30 байт, из которых 22 полезных и 8 служебных. На моём сервере (Xeon E5520, 2.24 ГГц) рассчёт одного пароля таким способом занимает 0.12 секунд — что очень много. На выходе будет получена строка длиной 60 байт.
Генератор позаимствован из комментариев на странице описания функции на php.net.
ссылка на оригинал статьи http://habrahabr.ru/post/159043/
Добавить комментарий