Совет по безопасности: Увеличьте раунды bcrypt

Источник: «Security Tip: Increase Your bcrypt Rounds»
Пришло время повысить количество раундов bcrypt до 12 (или выше)!

В статье приводится предыстория, но если нужно только краткое изложение, пропустите её!

bcrypt — функция хэширования паролей, используемая для защиты паролей в базах данных, чтобы их не мог определить и использовать тот, кто получит доступ к исходному хэшу. В настоящее время она является алгоритмом хэширования по умолчанию как в Laravel, так и в самом PHP, и на момент написания статьи это самый безопасный вариант хэширования паролей.

Время от времени возникают разговоры о переходе на Argon2, и его часто продвигают как лучшую альтернативу bcrypt, однако в Argon2 есть некоторые фундаментальные недостатки, делающие его неподходящим для веб-приложений. Этот вопрос поднимался в моем PR и в рассылки PHP internals, а один из экспертов, участвовавших в выборе Argon2, публично заявил, что выбор его был ошибочным.

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

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

Поэтому по мере роста вычислительной мощности необходимо повышать безопасность хэширования паролей. Это достигается за счёт Раундов / Стоимости / Рабочего Фактора, которые эффективно замедляют работу функции хэширования. Таким образом, если на генерацию хэша пароля уходит больше времени, то и на перебор хэшей паролей уходит больше времени, а для достаточно сложного пароля этот перебор становится невыполнимым в любом реалистичном сценарии.

Поддержка хеширования паролей с помощью bcrypt появилась в PHP 11 лет назад и по умолчанию составляла 10 раундов. Аналогично, в Laravel по умолчанию используется bcrypt и 10 раундов. Однако как я только что упомянул, вычислительные мощности постоянно растут, и 10 раундов уже не считаются достаточными для хэширования паролей. В связи с этим в PHP существует открытый RFC, позволяющий повысить значение по умолчанию с 10 до 11 или 122, и чтобы последовать их примеру, мы сделали то же самое в Laravel, повысив значение по умолчанию до 12.

RFC прошёл, и 12 было выбрано в качестве нового значения раундов по умолчанию в PHP 8.4.

Итак... всё это для того, чтобы сказать, что мы увеличили количество раундов bcrypt по умолчанию с 10 до 12!

Поскольку это значение определено в файле config/hashing.php, необходимо найти значение bcrypt.rounds и изменить его на 12 с 10.

'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 12),
],

Вот и всё! 🙂

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

Ещё немного теории: Мы выбрали 12 раундов, потому что, согласно бенчмаркам, генерация хэша всё ещё не достигает отметки 500 мс, после чего запросы, связанные с хэшированием, могут заметно замедлиться, и производительность системы может пострадать. Однако стоит отметить, что если вам требуется высокий уровень безопасности или у вас много ресурсов, вы можете увеличить количество раундов до 13+. Просто следите за влиянием производительности и выбирайте тот уровень, который вам подходит.

Обновление: Чтобы прояснить вопрос "почему именно сейчас?", следует сказать, что нам нужно быть проактивными в вопросах безопасности. С ростом вычислительных мощностей время вычисления хэша уменьшается, и тем легче становится перебирать хэши. OWASP рекомендует: "Как правило, вычисление хэша должно занимать менее одной секунды". Если совместить это с простыми бенчмарками, которые показывают, что на выполнение 10 раундов уходит менее 0,05 секунды, а на 12 — около 0,2-0,3 секунды, то преимущества в плане безопасности становятся очевидными.

Дополнительные материалы

Предыдущая Статья

Как создать универсальную сетку с помощью CSS Grid

Следующая Статья

Свободно экспериментируйте над кодом с Git worktree