Сбой password_verify для пароля, созданного на другом сервере

Я сталкиваюсь с ситуацией, когда у меня есть два сервера, которые сидят за балансировщиком нагрузки. Я использовал password_hash() для генерации пароля на одном сервере.

Что-то в принципе так

password_hash('XXXXXXXXX', PASSWORD_DEFAULT);

В моем приложении, когда я делаю запрос к конечной точке, которая использует password_verify(), когда запрос отправляется на сервер 1, пароль правильно проверяется, и запрос проверяется, однако, когда балансировщик нагрузки отправляет запрос на сервер 2, password_verify() появляется для быть не в состоянии подтвердить пароль.

Я проверил, что оба сервера используют одну и ту же версию PHP, скомпилированную в один день с PHP 7.1.2. Есть что-то еще, что мне здесь не хватает?

2 ответа

Кажется, что два сервера не поддерживают одинаковые алгоритмы, сервер1, вероятно, вычисляет хэш Argon2, а сервер2 еще не знает об этом алгоритме.

Вы можете исправить алгоритм на данный момент, это должно решить вашу проблему до тех пор, пока оба сервера не поймут оба алгоритма, тогда вам следует вернуться к PASSWORD_DEFAULT,

password_hash('XXXXXXXXX', PASSWORD_BCRYPT);

После прочтения о password_hash более подробно с http://php.net/manual/en/function.password-hash.php строка password_hash (строка $password, int $algo [, array $options ])

Я обнаружил, что использование password_hash('XXXXXXXXX', PASSWORD_DEFAULT);

не будет работать для балансировки нагрузки, по крайней мере, без серьезного изменения функции или использования собственной версии.

PASSWORD_DEFAULT выводит хешированный пароль, специфичный для этого экземпляра, на самом деле не вдаваясь в подробности, за исключением того, что опция соли не рекомендуется в php7+

Дополнительные опции для $algo (например, Argon2i) не были добавлены до php7.2, поэтому вам нужно будет обновить php7.1, так как на данный момент единственным вариантом является использование bycrypt, а стоимость - единственная опция.

http://php.net/manual/en/password.constants.php

В любом случае, это было постоянной проблемой даже для серверов oauth с балансировкой нагрузки. Когда сгенерированный токен на сервере 1 не будет работать для сервера 2. Одним из способов решения этой проблемы является использование общего кэша и базы данных, что не позволяет распределить нагрузку на отдельное оборудование и даже разные сети. Другим вариантом является использование функции закрепления на балансировщике нагрузки.

Одной вещи, которую следует избегать, является использование тех же самых солей для вашего хэша, чтобы обойти эту проблему. Работа со следующими шагами для хеширования должна работать на всех ваших серверах, если вы используете одну и ту же базу данных.

Создайте длинную случайную соль, используя CSPRNG или любой другой метод генерации случайных солей. Интересное примечание: аппаратные / физические генераторы случайных чисел, такие как Lavarand. Добавьте соль к паролю и хэшируйте его с помощью стандартной функции хеширования пароля, такой как Argon2i. Сохраните и соль, и хеш в записи базы данных пользователя.

Получить соль пользователя и хэш из базы данных. Добавьте соль к заданному паролю и хешируйте его, используя ту же хеш-функцию. Сравните хеш данного пароля с хешем из базы данных. Если они совпадают, пароль правильный. В противном случае пароль неверен.

например ---

<?php

$salt = random_bytes(100);

$password = 'password';

$combined = '$password' + $salt;


$hash = password_hash('$combined', PASSWORD_DEFAULT);

if (password_verify('$combined', $hash)) {

    echo 'true';
} else { 
    echo 'no go';
}
Другие вопросы по тегам