На прошлой неделе я прочитал много статей о хэшировании паролей, и Blowfish кажется (одним из) лучшим алгоритмом хэширования прямо сейчас, но это не тема этого вопроса!
Предел 72 символов
Blowfish рассматривает только первые 72 символа введенного пароля:
<?php
$password = "Wow. This is a super secret and super, super long password. Let add some special ch4r4ct3rs a#d everything is fine :)";
$hash = password_hash($password, PASSWORD_BCRYPT);
var_dump($password);
$input = substr($password, 0, 72);
var_dump($input);
var_dump(password_verify($input, $hash));
?>
Вывод:
string(119) "Wow. This is a super secret and super, super long password. Let add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let add so"
bool(true)
Как вы можете видеть только первые 72 символа. Twitter использует blowfish aka bcrypt для хранения своих паролей (https://shouldichangemypassword.com/twitter-hacked.php) и угадайте, что: измените свой пароль Twitter на длинный пароль с более чем 72 символов, и вы можете войти в свою учетную запись, введя только первые 72 символа.
Blowfish and Pepper
Есть много разных мнений о "переполненных" паролях. Некоторые люди говорят, что это не нужно, потому что вы должны предположить, что секретная перечная строка также известна/опубликована, поэтому она не улучшает хэш. У меня есть отдельный сервер базы данных, поэтому вполне возможно, что просочилась только база данных, а не постоянный перец.
В этом случае (перец не просочился) вы делаете атаку на основе словаря более сложной (исправьте меня, если это неверно). Если ваша перечная струна также просочилась: не так уж плохо - у вас все еще есть соль, и она защищена как хэш без перца.
Таким образом, я думаю, что надуть пароль - это, по крайней мере, плохой выбор.
Предложение
Мое предложение получить хеш Blowfish для пароля с более чем 72 символами (и перцем):
<?php
$pepper = "foIwUVmkKGrGucNJMOkxkvcQ79iPNzP5OKlbIdGPCMTjJcDYnR";
// Generate Hash
$password = "Wow. This is a super secret and super, super long password. Let add some special ch4r4ct3rs a#d everything is fine :)";
$password_peppered = hash_hmac('sha256', $password, $pepper);
$hash = password_hash($password_peppered, PASSWORD_BCRYPT);
// Check
$input = substr($password, 0, 72);
$input_peppered = hash_hmac('sha256', $input, $pepper);
var_dump(password_verify($input_peppered, $hash));
?>
Это основано на этом вопросе: password_verify
return false
.
Вопрос
Чем безопаснее? Сначала получить хэш SHA-256 (который возвращает 64 символа) или рассмотреть только первые 72 символа пароля?
Pros
- Пользователь не может войти, введя только первые 72 символа
- Вы можете добавить перец без превышения лимита символов
- Выход hash_hmac, вероятно, будет иметь больше энтропии, чем сам пароль
- Пароль хешируется двумя различными функциями
Против
- Только 64 символа используются для создания хэша blowfish
Изменить 1: Этот вопрос касается только интеграции PHP blowfish/bcrypt. Спасибо за комментарии!