Как хешировать длинные пароли (> 72 символов) с помощью blowfish
На прошлой неделе я прочитал много статей о хешировании паролей, и Blowfish, кажется, (один из) лучший алгоритм хеширования сейчас - но это не тема этого вопроса!
Ограничение в 72 символаBlowfish учитывает только первые 72 символа введенного пароля:
<?php
$password = "Wow. This is a super secret and super, super long password. Let's 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's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add so"
bool(true)
Как видите, только первые 72 символа имеют значение. Твиттер использует blowfish aka bcrypt для хранения своих паролей (https://shouldichangemypassword.com/twitter-hacked.php) и угадайте, что: измените свой пароль в твиттере на длинный пароль длиной более 72 символов, и вы сможете войти в свою учетную запись, введя только первые 72 символа.
Морская рыба и перецСуществует много разных мнений по поводу «перетекания» паролей. Некоторые люди говорят, что это не нужно, потому что вы должны предположить, что секретная перечная строка также известна / опубликована, поэтому она не увеличивает хэш. У меня есть отдельный сервер базы данных, поэтому вполне возможно, что только база данных просочилась, а не постоянный перец.
В этом случае (перец не просочился) вы делаете атаку на основе словаря более сложной (поправьте меня, если это не так). Если ваша перчинка тоже протекла: не так уж и плохо - у вас все еще есть соль, и она так же хорошо защищена, как хеш без перца.
Так что я думаю, что перебросить пароль, по крайней мере, не плохой выбор.
ПредложениеМое предложение получить хэш Blowfish для пароля длиной более 72 символов (и перца):
<?php
$pepper = "foIwUVmkKGrGucNJMOkxkvcQ79iPNzP5OKlbIdGPCMTjJcDYnR";
// Generate Hash
$password = "Wow. This is a super secret and super, super long password. Let's 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
вернутьfalse
.
Какой безопасный способ? Сначала получить хеш SHA-256 (который возвращает 64 символа) или учитывать только первые 72 символа пароля?
ProsПользователь не может войти, введя только первые 72 символаВы можете добавить перец без превышения лимита символовВывод hash_hmac, вероятно, будет иметь большую энтропию, чем сам парольПароль хешируется двумя разными функциямиConsТолько 64 символа используются для создания хэша BlowfishИзменить 1: Этот вопрос касается только PHP-интеграции blowfish / bcrypt. Спасибо за комментарии!