crypt():在相同的PHP环境下,不同的服务器上的行为不同


crypt(): different behaviour on different servers despite same PHP environment

我目前正在设置一个暂存环境,在此环境中我遇到了PHP crypt()的问题。我们将相同的代码和相同的数据部署到相同的环境中(Ubuntu 14.04, Apache 2.2.25, PHP 5.4.17, mySQL 5.6.11,所有内容都由相同的设置脚本设置),但我们无法登录到我们的平台。使用crypt()对密码进行散列,如下所示:

$saltedPassword = $userSalt . $userInput . $systemSalt;
$randomSalt = someFunctionWithMtRandOutputting22Chars();
$hash = crypt($saltedPassword, '$2y$15$' . $randomSalt);
$userDao->storePassword($hash);

$userSalt是与用户绑定的常量日期(如他的ID), $userInput是前端发送的实际密码。一个例子是$2y$15$X8ozNErDV1SU1wdTdAW7JOg/eYt4C7okLB0.9pR9HkM.fqtj7/H.e

要登录,门户使用以下代码:
$hash = $userDao->getPassword();
$saltedPassword = $userSalt . $userInput . $systemSalt;
$authorized = (crypt($saltedPassword, $hash) === $encryptedPassword);
// if $authorized === true, login

这段代码在5台不同的机器(生产和开发)上运行得很好。当在stage环境中使用相同的代码时,第二个crypt()调用返回不同的结果,在本例中为$2y$15$X8ozNErDV1SU1wdTdAW7JOsxs7kdiTp3Bp0QuuOUcYs6zXkaq6dgq。虽然密码的盐部分是相同的(并且表明选择了正确的算法[Blowfish]),但第二部分与存储的散列不同。

我在所有系统上测试了已知常数(CRYPT_SALT_LENGTHCRYPT_BLOWFISH),所有值都是相同的。我在命令行上测试了代码,所有系统都返回了相同的散列,但令人惊讶的是,不是存储在数据库中的散列,而是"错误"的散列。这可能是一个错误配置的提示吗?

现有的工作环境和新的故障阶段环境之间唯一已知的区别是,阶段环境在我们的测试服务器上被设置为chroot环境。这种差异会导致我的问题吗?

我发现了问题:我的假设,即舞台环境上的数据是相同的,是错误的。在浏览了一些测试数据后,我们发现$userSalt在结构上与其他系统不同,这表明数据库设置例程中存在错误。