Я работаю над существующим проектом веб-приложения Symfony
2.8, который использует FOSUserBundle
для аутентификации пользователя.
В дополнение к веб-интерфейсу пользователи могут использовать другой клиент смартфона для подключения к веб-приложению с использованием REST API. Таким образом, пользователи должны быть аутентифицированы как при входе в систему непосредственно в веб-приложении, так и при подключении, почему REST API.
Пока один из последних FOSUserBundle
не обновит хеш пароля bcrypt
и использованный salt
, который хранится в базе данных.
При подключении с использованием REST API соль передается клиенту для локального хэша пароля с использованием той же соли. Хешированный пароль, чем отправка обратно в веб-приложение для аутентификации.
Я знаю, что отправка хешированного пароля вместо обычного текста не добавляет (много) дополнительной безопасности, поскольку связь возможна только с использованием HTTPS. Однако именно так работают клиенты: им нужна соль для генерации хешированного пароля. Я могу обновить клиентов в будущем, но сейчас это именно то, как работа.
Проблема:
Их путь FOSUserBundle
хэширует пароль изменился: так как считается, что он НЕ должен указывать соль вручную, но позволяет PHP генерировать соль автоматически (в PHP 7 не возможно даже вручную установить соль), руководство соль больше не поддерживается.
Это не проблема при входе в веб-приложение напрямую, но поскольку клиентам REST по-прежнему нужна соль, это обновление нарушает соединение REST.
Есть ли способ объединить оба метода? Пусть PHP автоматически создает соль, извлекает и отправляет эту соль клиентам?
Насколько я понимаю, соль хранится с хешем в той же строке:
Однако просто скопируйте соль 21 char из хэш-строки и отправьте их клиентам не работает. Кажется, что этих 21 символов достаточно для проверки/проверки пароля, но не для повторного создания хэша. Правильно ли это?
Итак, есть ли какое-либо решение использовать PHP password_hash
без установки соли и одновременное знакомство с используемой солью?
РЕДАКТИРОВАТЬ 1:
Чтобы ответить на вопрос @RiggsFolly: MD5 не использовался в любое время. Это не правильно, что bcryp
/password_hash
не будет создавать один и тот же хэш дважды. Он будет делать это, если оба пароля и соль одинаковы:
$s = 'password';
$salt = 'salt5678901234567890123456789012';
$options['salt'] = $salt;
$h1 = password_hash($s,PASSWORD_BCRYPT,$options);
$h2 = password_hash($s,PASSWORD_BCRYPT,$options);
echo $h1 . PHP_EOL;
echo $h2 . PHP_EOL;
Результат:
$2y$10$salt56789012345678901uTWNlUnhu5K/xBrtKYTo7oDy8zMr/csu
$2y$10$salt56789012345678901uTWNlUnhu5K/xBrtKYTo7oDy8zMr/csu
password_hash
создаст новый хеш для того же пароля, если соль не указана. Это связано с тем, что соль будет создаваться случайным образом, чем причина разницы в каждом вызове.
ИЗМЕНИТЬ 2:
Как видно в Редактировании 1, использование соли с 32 символами приведет к строке, которая включает только первые 21 символ соли. Однако этот префикс соля не может использоваться для повторного создания одного и того же хэша, поскольку он слишком короткий для принятия.
Однако, если префикс заполнен 0, он, похоже, работает:
$s = 'password';
$salt = 'salt5678901234567890123456789012';
$salt_prefix = 'salt5678901234567890100000000000';
$h1 = password_hash($s, PASSWORD_BCRYPT, array('salt' => $salt));
$h2 = password_hash($s, PASSWORD_BCRYPT, array('salt' => $salt_prefix));
echo $h1 . PHP_EOL;
echo $h2 . PHP_EOL;
Таким образом, решение может быть:
- let
FOSUserBundle
используйтеpassword_hash
, чтобы создать хеш без вручную, указав соль. - извлеките соль из строки результата и нанесите ее на 0 до 32 символов
- передать эту соль клиенту
Может ли кто-нибудь подтвердить, что это настоящее решение, а не просто какое-то совпадение?