使用 pgcrypto 验证 password_hash 生成的密码

Use pgcrypto to verify passwords generated by password_hash

我将密码散列存储在生成的 Postgresql 数据库中:

password_hash($password, PASSWORD_DEFAULT);

现在我还希望能够使用 Postgresql 和 pgcrypto 验证用户密码。

但是 pgcrypto 的 crypt() 函数无法验证现有的密码哈希值。

但是 - 我可以使用 PHP 的 password_verify.

验证 Postgresql 生成的密码哈希

例如:

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

验证:

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

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

我的问题基本上是:

来自以下问题的答案:Where 2x prefix are used in BCrypt? 其中包含有关因实施错误而产生的 $2$ 变体的所有详细信息:

There is no difference between 2a, 2x, 2y, and 2b. If you wrote your implementation correctly, they all output the same result.

基于此,可以采用 PHP 的 password_hash 生成的散列,将前导 y$ 替换为 a$ 并将其作为第二个参数传递pgcrypto 的 crypt().

使用示例中的值:

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

postgres=# SELECT crypt('hello', :'hash') = :'hash'
 ?column? 
----------
 t