有时我们知道数据库中的密码,但是却不知道加密之前的密码,一个一个试又浪费时间,如何通过脚本批量测试? 以下从设置密码开始逐步分析:
设置密码:
调用的是 base模块中res_users文件中的
_set_password函数,通过sha512算法加密,如下所示:
DEFAULT_CRYPT_CONTEXT = passlib.context.CryptContext(
# kdf which can be verified by the context. The default encryption kdf is
# the first of the list
['pbkdf2_sha512', 'plaintext'],
# deprecated algorithms are still verified as usual, but ``needs_update``
# will indicate that the stored hash should be replaced by a more recent
# algorithm. Passlib 1.6 supports an `auto` value which deprecates any
# algorithm but the default, but Ubuntu LTS only provides 1.5 so far.
deprecated=['plaintext'],
)
对于同一个密码,该算法每次加密出来的结果都不一致。
登录机制:
最终调用的也是 base模块中 res_users文件中的_check_credentials方法:
def _check_credentials(self, password):
assert password
self.env.cr.execute(
"SELECT COALESCE(password, '') FROM res_users WHERE id=%s",
[self.env.user.id]
)
[hashed] = self.env.cr.fetchone()
valid, replacement = self._crypt_context()\
.verify_and_update(password, hashed)
if replacement is not None:
self._set_encrypted_password(self.env.user.id, replacement)
if not valid:
raise AccessDenied()
该方法会查出当前用户名的在数据库中加密之后的密码,然后再调用 passlib模块中的方法验证密码,使用的对象和设置密码的对象是同一个对象,self._crypt_context().verify_and_update(password, hashed)。
self._crypt_contect()就是上述中的DEFAULT_CRYPT_CONTEXT对象。
综上所述:
如果出现密码忘记的情况,可以将数据库中的hash值取出来,循环调用 verify_and_update方法验证多个可能的密码
创建验证密码的脚本:
from passlib.context import CryptContext
DEFAULT_CRYPT_CONTEXT = CryptContext(
# kdf which can be verified by the context. The default encryption kdf is
# the first of the list
['pbkdf2_sha512', 'plaintext'],
# deprecated algorithms are still verified as usual, but ``needs_update``
# will indicate that the stored hash should be replaced by a more recent
# algorithm. Passlib 1.6 supports an `auto` value which deprecates any
# algorithm but the default, but Ubuntu LTS only provides 1.5 so far.
deprecated=['plaintext'],
)
k='''
$pbkdf2-sha512$25000$HsNYi/Heu7e21hqjNMa4Vw$LqnIuUp18/uz/Vxa1Fp/nLItrJle/14ZYUizvK5npMe1X8.QEyEp/ovq6dlX3aKwz9nHMAB07B6sVz4G9U934Q
$pbkdf2-sha512$25000$915rLSXkHGPs/d/7v/e.Vw$zlPOYR8JACpkDla4.M4BmIsViDUXrHEIn9nlK/ew9jGlJzLUTYVmZ3xtgPP5mJyWYQP2o/AwcALOWaA89Ws1zw
'''
password_list = k.split('\n')
for password in password_list:
print(DEFAULT_CRYPT_CONTEXT.verify_and_update('xxx',password),password)
打印结果:
其中 password_list 为 数据库中取出来的密码加密列表
如果 打印结果为 true则表示 数据库中的加密是由 密码 xxx加密而来