Laravel хешує паролі через Hash::make() (і каст hashed у моделі User). Налаштування - у config/hashing.php.
Алгоритм за замовчуванням - bcrypt з вартістю (BCRYPT_ROUNDS) 12: кожне збільшення на 1 подвоює час обчислення. Альтернатива - Argon2id (HASH_DRIVER=argon2id) з параметрами пам'яті, часу й потоків (ARGON_MEMORY, ARGON_TIME, ARGON_THREADS).
bcrypt чи Argon2id:
- Argon2id - сучасний рекомендований OWASP варіант: вимагає багато пам'яті, тому перебір на GPU й спеціалізованих чипах значно дорожчий;
- bcrypt - перевірений часом, доступний усюди, але має обмеження в 72 байти: усе, що довше, ігнорується. Пароль з 80 символів і той самий пароль з іншими останніми символами дадуть однаковий хеш. Для кирилиці (2 байти на символ) межа - ~36 символів. Laravel має параметр
BCRYPT_LIMIT, щоб відхиляти задовгі паролі замість мовчазного обрізання.
Як обирати вартість: обчислення хешу має займати приблизно сотні мілісекунд на вашому сервері. Менше - легше перебирати при витоку бази; більше - повільний вхід і можливість DoS через масові спроби входу. Вартість варто переглядати разом з обладнанням.
Повторне хешування при вході. У Laravel 11+ rehash_on_login увімкнено за замовчуванням: при успішному вході Laravel перевіряє, чи хеш створено з поточними налаштуваннями, і якщо ні - перехешовує пароль (відкритий текст на цей момент відомий). Тому підвищення BCRYPT_ROUNDS чи перехід на Argon2id відбуваються поступово, без примусового скидання паролів.
verify (HASH_VERIFY=true) - перевірка, що хеш створено очікуваним алгоритмом. Захищає від ситуацій, коли в базі опиняються хеші іншого типу (наприклад, після імпорту), що перевірялися б іншим, можливо слабшим, способом.
Ручне перехешування:
if (Hash::needsRehash($user->password)) {
$user->password = Hash::make($plainPassword);
$user->save();
}
Типові помилки:
md5,sha1,sha256для паролів - швидкі хеші, мільярди перевірок за секунду на GPU;- шифрування паролів замість хешування;
- власна «сіль» чи комбінації алгоритмів -
password_hashі Laravel уже додають сіль автоматично; - знижена вартість у продакшені через
BCRYPT_ROUNDSз тестового.env: у тестах низька вартість доречна для швидкості (phpunit.xmlзадаєBCRYPT_ROUNDS=4), але не на сервері.