【发布时间】:2020-04-05 21:39:44
【问题描述】:
我正在迁移一个使用未加盐 MD5 密码的旧系统(太可怕了!)。
我知道 Django handles automatically password upgrading,当用户登录时,通过在 settings.py 的 PASSWORD_HASHERS 列表中添加额外的哈希器。
但是,我想升级密码而不要求用户登录,also explained in the docs。
所以,我按照文档中的示例实现了一个自定义哈希器,legacy/hasher.py:
import secrets
from django.contrib.auth.hashers import PBKDF2PasswordHasher, UnsaltedMD5PasswordHasher
class PBKDF2WrappedMD5PasswordHasher(PBKDF2PasswordHasher):
algorithm = "pbkdf2_wrapped_md5"
def encode_md5_hash(self, md5_hash):
salt = secrets.token_hex(16)
return super().encode(md5_hash, salt)
def encode(self, password, salt, iterations=None):
md5_hash = UnsaltedMD5PasswordHasher().encode(password, salt="")
return self.encode_md5_hash(md5_hash)
并将其添加到settings.py:
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"legacy.hashers.PBKDF2WrappedMD5PasswordHasher",
]
但是,在 Django shell check_password 中对此进行测试会为升级后的密码返回 False。
>>> from django.contrib.auth.hashers import check_password, UnsaltedMD5PasswordHasher
>>> from legacy.hashers import PBKDF2WrappedMD5PasswordHasher
>>> hasher = PBKDF2WrappedMD5PasswordHasher()
>>> test_pwd = '123456'
>>> test_pwd_unsalted_md5 = UnsaltedMD5PasswordHasher().encode(test_pwd, salt='')
>>> print(test_pwd_unsalted_md5)
'827ccb0eea8a706c4c34a16891f84e7b' # this is an example of a password I want to upgrade
>>> upgraded_test_pwd = hasher.encode_md5_hash(test_pwd)
>>> print(upgraded_test_pwd)
pbkdf2_wrapped_md5$150000$f3aae83b02e8727a2477644eb0aa6560$brqCWW5QuGUoSQ28YNPGUwTLEwZOuMNheN2RxVZGtHQ=
>>> check_password(test_pwd, upgraded_test_pwd)
False
【问题讨论】:
-
你在这里自己生成
salt,你不会“存储”在目标密码中。