我有一个PHP7应用,它会像这样散布用户密码
$hash = password_hash($password, PASSWORD_BCRYPT);
例如,如果我通过test1234
,我将得到:
$2y$10$aazE9OUKZlOQiM6axwxU/utpOURLQ58pluqtFZkkGE3R9ShtUxBOm
现在,我有一个Python应用程序,该应用程序也必须更新用户密码。它使用的是这样的:
import bcrypt
hash = bcrypt.hashpw(password, bcrypt.gensalt())
例如,相同的密码test1234
散列为:
$2a$12$vsI9Vf9gWj/Au3McYradxuozyZychmlfqoCJcSacDWuMzUDVpv33m
如您所见,PHP在$2y
中生成了$2a
,而Python在$result = password_verify($password, $hash);
中做了,因此它们是散列的不同版本。
现在,如果我尝试验证PHP中的Python和PHP哈希,就像这样:
true
两种情况下我都有bcrypt.checkpw(password, hash)
。但是,如果我尝试在Python方面进行验证:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Invalid hashed_password salt
仅当我传递Python中生成的哈希值时才适用。如果我通过PHP生成的哈希,我将:
bcrypt
我的问题:我想念什么吗?
py-bcrypt
模块由我使用pip安装的pip3 install py-bcrypt
项目0.4版提供:
DateEntry
答案 0 :(得分:3)
2y
和2a
是two different versions of the bcrypt algorithm。正如Wikipedia所述,2y
仅仅适用于PHP :
2011年6月,在
crypt_blowfish
(BCrypt的PHP实现)中发现了一个错误。 [...] 他们还提出了让crypt_blowfish针对由固定算法生成的散列发出$2y$
的想法。其他人,包括规范的OpenBSD,都没有采用2x / 2y的想法。此版本标记更改仅限于
crypt_blowfish
。
py-bcrypt
模块落后于时代,因为它仅支持2a
版本!截至2014年2月,版本2b是当前版本(修正了超过255个字符的错误哈希密码)。当前的0.4版本是在2013年发布的,因此我认为该项目已经死了。
相反,您应该安装bcrypt
project。虽然它仅支持2a
和2b
来生成散列值,但它显式地supports normalising 2y
hashes to treat them as 2b
hashes,因此我可以毫无疑问地验证2y
哈希项目:
>>> import bcrypt
>>> bcrypt.__version__
'3.1.4'
>>> hash = b'$2y$10$aazE9OUKZlOQiM6axwxU/utpOURLQ58pluqtFZkkGE3R9ShtUxBOm'
>>> bcrypt.checkpw(b'test1234', b'$2y$10$aazE9OUKZlOQiM6axwxU/utpOURLQ58pluqtFZkkGE3R9ShtUxBOm')
True