使用
django
管理员,我创建了一个用户
email: [email protected]
password: ccpass!ccpass
数据库中存储的哈希密码是
pbkdf2_sha256$260000$alGB1h2BRHwn83nz9fSJ3V$qippfbL8g59KPoDh+cIEh70TQCjuWeH8017VcLLpDIY=
我所知道的是
django
正在使用 PBKDF2
算法生成密码哈希。
我需要运行一个纯Python脚本,它在其中的一部分检查密码是否与哈希匹配。我找到了一个图书馆
passlib
。我可以提供密码和回合。但姜戈盐从哪里来呢?
from passlib.hash import pbkdf2_sha256
password = 'ccpass!ccpass'
db_hashed_password = 'pbkdf2_sha256$260000$alGB1h2BRHwn83nz9fSJ3V$qippfbL8g59KPoDh+cIEh70TQCjuWeH8017VcLLpDIY='
salt = db_hashed_password.split('$')[2].encode()
pbkdf2_sha256.hash(password, rounds=260000, salt=salt)
结果:
$pbkdf2-sha256$260000$YWxHQjFoMkJSSHduODNuejlmU0ozVg$qippfbL8g59KPoDh.cIEh70TQCjuWeH8017VcLLpDIY
生成的密码散列除了细微差别外显然看起来相同。
pbkdf2-sha256
有破折号而不是下划线,但这不是问题。我可以修复它。
主要问题是我确实收到了
.
而不是实际哈希部分中的 +
。如何解决这个问题?我可以盲目地将所有.
替换为+
吗?
我也不明白为什么计算出来的盐和原来的盐不一样?
我遵循了
django
源代码。
看看encode函数和pbkdf2函数,我可以编写以下代码:
import base64
import hashlib
myhash = base64.b64encode(hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 260000, None)).decode("ascii").strip()
print("%s$%d$%s$%s" % ('pbkdf2_sha256', 260000, salt.decode(), myhash))
这个纯Python代码给了我与django相同的结果:
pbkdf2_sha256$260000$alGB1h2BRHwn83nz9fSJ3V$qippfbL8g59KPoDh+cIEh70TQCjuWeH8017VcLLpDIY=
.
Django 使用 django_pbkdf2_sha256 ,与 pbkdf2_sha256 不同
https://passlib.readthedocs.io/en/stable/lib/passlib.hash.django_std.html#django-1-4-hashes
>>> from passlib.hash import django_pbkdf2_sha256 as handler
>>> # hash password
>>> h = handler.hash("password")
>>> h
'pbkdf2_sha256$10000$s1w0UXDd00XB$+4ORmyvVWAQvoAEWlDgN34vlaJx1ZTZpa1pCSRey2Yk='
>>> # verify password
>>> handler.verify("password", h)
True
>>> handler.verify("eville", h)
False
使用哈希工具可以看到哈希是Django (PBKDF2-HMAC-SHA256)