password_verify无法在另一台服务器上创建密码

时间:2018-10-16 08:10:00

标签: php bcrypt password-hash php-password-hash

我遇到一种情况,我有两个服务器位于负载均衡器后面。我使用password_hash()在一台服务器上生成密码。

基本上是这样的

password_hash('XXXXXXXXX', PASSWORD_DEFAULT);

在我的应用程序中,当我向使用服务器1的端点发送使用password_verify()的端点的请求时,密码已正确验证并验证了请求,但是当负载平衡器将请求发送到服务器2时password_verify( )似乎无法验证密码。

我已验证两台服务器都使用完全相同的PHP版本,并在同一天运行PHP 7.1.2进行编译。这里还有我想念的东西吗?

2 个答案:

答案 0 :(得分:0)

详细了解了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 +中salt选项已弃用

之外,它并没有涉及太多细节

直到{php1}才添加$algo(如Argon2i)的更多选项,因此您需要从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';
}

答案 1 :(得分:0)

这两个服务器似乎不支持相同的算法,server1可能会计算Argon2哈希,而server2尚不知道此算法。

您可以暂时修复算法,这将解决问题,直到两台服务器都了解这两种算法为止,然后应切换回PASSWORD_DEFAULT

password_hash('XXXXXXXXX', PASSWORD_BCRYPT);