Как хешировать длинные пароли (> 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. Спасибо за комментарии!

Ответы на вопрос(3)

Ваш ответ на вопрос