Код:
echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-characters'] );
Результат:
Warning: password_hash(): Provided salt is too short: 21 expecting 22
код:
echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-charactersA'] );
Результат:
$2y$10$dHdlbnR5LW9uZS1jaGFyYOVyX13hK9eb4/KXMAkHsAJX..YR7t/32
код:
echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-charactersB'] );
$2y$10$dHdlbnR5LW9uZS1jaGFyYOVyX13hK9eb4/KXMAkHsAJX..YR7t/32
Вопрос:
Как видите, добавив A и B к 21 символьной строке, мы создали две разные соли по 22 символа, но HASHES одинаковы! То есть 22-й символ игнорируется? Если он игнорируется, то почему он запрашивает 22 символа соли?
BCrypt ожидает соль заданного алфавита: ./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
, Как видите, в нем нет «-», и поэтому ваша соль недействительна. Действительная соль, которую вы могли видеть в виде открытого текста в хэш-значении.
В большинстве случаев лучше не указывать параметр соли. Без этого параметра функция будет генерировать криптографически безопасную соль из случайного источника операционной системы.
password_hash("stackoverflow", PASSWORD_DEFAULT);
Тем не менее вы правы, когда говорите, что BCrypt не использует полные 22 символа. Похоже, что BCrypt использует только 126 бит соли вместо 128 бит, которые вы получаете с 22 символами в кодировке base64. Для получения дополнительной информации вы можете посмотреть на это обсуждение Почему crypt / blowfish генерирует такой же хэш ….
Первый, пожалуйста не давай свою соль. Вы не будете выполнять свою работу лучше, чем библиотека. И используя статические соли (как вы сделали в примере) будут компромисс безопасности. Просто позвольте ему генерировать свою собственную соль (кстати, я считаю, что добавление соли — самая большая ошибка, которую я сделал в этом API).
Насколько 21 против 22 символов, дать этот ответ читать.
По сути, соль кодируется base64. Это означает, что каждые 6 битов соли кодируются в 8 битов. Таким образом, каждый байт кодированной соли составляет 6 бит.
21 символ — это 126 бит. Это означает, что используется только часть 22-го символа (первые 2 декодированных бита). Причина, по которой вы получаете такой же хэш A
а также B
является то, что первые 2 бита одинаковы для обоих символов.
На самом деле, есть только 4 уникальных хэша для 22-го байта.