сбой password_verify для пароля, созданного на другом сервере - PullRequest
0 голосов
/ 16 октября 2018

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

Что-то вроде этого

password_hash('XXXXXXXXX', PASSWORD_DEFAULT);

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

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

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

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

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

password_hash('XXXXXXXXX', PASSWORD_BCRYPT);
0 голосов
/ 16 октября 2018

После прочтения о password_hash более подробно из

http://php.net/manual/en/function.password-hash.php

string password_hash ( string $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';
}
...