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
2y
和 2a
是 two 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
我有一个 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
2y
和 2a
是 two 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 emity$
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