Migrate bcrypt password hash from PHP to Python - ValueError: Invalid hashed_password salt

Migrate bcrypt password hash from PHP to Python - ValueError: Invalid hashed_password salt

我有一个 PHP7 应用程序可以像这样散列用户密码

$hash = password_hash($password, PASSWORD_BCRYPT);

例如,如果我将 test1234 传递给它,我得到:

y$aazE9OUKZlOQiM6axwxU/utpOURLQ58pluqtFZkkGE3R9ShtUxBOm

现在,我有一个 Python 应用程序,它也必须更新用户密码。它使用这样的东西:

import bcrypt

hash = bcrypt.hashpw(password, bcrypt.gensalt())

例如,相同的密码 test1234 散列为:

a$vsI9Vf9gWj/Au3McYradxuozyZychmlfqoCJcSacDWuMzUDVpv33m

如您所见,PHP 生成了 y,而 Python 生成了 a - 所以它们是散列的不同版本。

现在,如果我尝试验证 Python 和 PHP 哈希值,在 PHP 中像这样:

$result = password_verify($password, $hash);

我在这两种情况下都有 true。但是,如果我尝试在 Python 方面验证两者:

bcrypt.checkpw(password, hash)

它仅适用于我传递在 Python 中生成的哈希值时的情况。如果我传递在 PHP 中生成的哈希值,我得到:

Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ValueError: Invalid hashed_password salt

我的问题:有什么我遗漏的吗?

bcrypt 模块由我使用 pip 安装的 py-bcrypt 项目版本 0.4 提供:

pip3 install py-bcrypt

2y2atwo different versions of the bcrypt algorithm。正如维基百科所述,2y 特定于 PHP:

In June 2011, a bug was discovered in crypt_blowfish, a PHP implementation of BCrypt. [...] They also suggested the idea of having crypt_blowfish emit y$ for hashes generated by the fixed algorithm.

Nobody else, including canonical OpenBSD, adopted the idea of 2x/2y. This version marker change was limited to crypt_blowfish.

py-bcrypt模块在这里落后了,因为它只支持2a版本!截至 2014 年 2 月,版本 2b 是当前版本(修复了长度超过 255 个字符的散列密码错误)。当前的 0.4 版本是在 2013 年发布的,所以我认为这个项目此时已经死亡。

相反,您应该安装 bcrypt project. While it only supports 2a and 2b to generate hashes, it explicitly supports normalising 2y hashes to treat them as 2b hashes,因此我使用该项目验证 2y 哈希没有问题:

>>> import bcrypt
>>> bcrypt.__version__
'3.1.4'
>>> hash = b'y$aazE9OUKZlOQiM6axwxU/utpOURLQ58pluqtFZkkGE3R9ShtUxBOm'
>>> bcrypt.checkpw(b'test1234', b'y$aazE9OUKZlOQiM6axwxU/utpOURLQ58pluqtFZkkGE3R9ShtUxBOm')
True