Используйте pgcrypto для проверки паролей, сгенерированных password_hash.

У меня есть хэши паролей, хранящиеся в базе данных Postgresql, сгенерированные с помощью:

password_hash($password, PASSWORD_DEFAULT);

Теперь я хотел бы также иметь возможность проверить пароль пользователя с помощью Postgresql и pgcrypto.

Но функция pgcrypto crypt() не может проверить существующие хэши паролей.

Однако я могу проверить хэши паролей, сгенерированные Postgresql, с помощью PHP password_verify.

Например:

password_hash('hello', PASSWORD_DEFAULT);
$2y$10$fD2cw7T6s4dPvk1SFHmiJeRRaegalE/Oa3zSD6.x5WncQJC9wtCAS
postgres=# SELECT crypt('hello', gen_salt('bf'));
                            crypt                             
--------------------------------------------------------------
 $2a$06$7/AGAXFSTCMu9r.08oD.UulYR0/05q7lmuCTC68Adyu/aNJkzpoIW

Проверка:

// php_verify with the Postgresql hash
php > var_dump(password_verify('hello', '$2a$06$7/AGAXFSTCMu9r.08oD.UulYR0/05q7lmuCTC68Adyu/aNJkzpoIW'));
bool(true)

postgres=# SELECT crypt('hello', '$2y$10$fD2cw7T6s4dPvk1SFHmiJeRRaegalE/Oa3zSD6.x5WncQJC9wtCAS');
     crypt     
---------------
 $2JgKNLEdsV2E
(1 Zeile)

Мои вопросы в основном:

  • Я делаю это неправильно?
  • Если это невозможно: есть ли путь миграции, чтобы сделать это возможным?

person madflow    schedule 07.04.2019    source источник
comment
$2y$ — это специфичный для PHP алгоритм, поскольку в его реализации $2a$ была ошибка, IIRC. Проблема, вероятно, в том, что очень немногие другие системы поддерживают его.   -  person deceze♦    schedule 07.04.2019


Ответы (1)


Из ответа на: Где префикс 2x используется в BCrypt?, в котором есть все кровавые подробности о вариантах $2$, порожденных ошибками реализации. :

Нет разницы между 2a, 2x, 2y и 2b. Если вы правильно написали свою реализацию, все они выведут один и тот же результат.

Исходя из этого, можно взять хеш, сгенерированный PHP password_hash, заменить начальный $2y$ на $2a$ и передать его в качестве второго аргумента pgcrypto crypt().

Используя значение из вашего примера:

postgres=# \set hash '$2a$10$fD2cw7T6s4dPvk1SFHmiJeRRaegalE/Oa3zSD6.x5WncQJC9wtCAS'

postgres=# SELECT crypt('hello', :'hash') = :'hash'
 ?column? 
----------
 t
person Daniel Vérité    schedule 07.04.2019
comment
Вау... Спасибо, что поделились/расследовали это! - person madflow; 08.04.2019