我如何重新计算 web2py 的密码哈希值?

How do I recompute web2py's password hash?

我正在尝试让另一个应用程序(运行 在不同的堆栈上)通过我现有的运行 web2py 的应用程序进行身份验证。我想了解如何使用 auth_user?

中的密码验证输入的密码

我确实看到了 https://groups.google.com/forum/#!topic/web2py/tLAiqRaXG48,但我无法从那里得到它。这是我正在做的事情:

导入哈希库 从 pbkdf2 导入地穴 crypt(hashlib.sha512("MyPassword").hexdigest(),迭代次数=1000)

我在数据库中的密码是这样的:

pbkdf2(1000,20,sha512)$b787f1e6dfe7da8f$b280b42a152aa14a1944d35c6a070521251b85d1

(稍微更改了哈希本身)

如有任何帮助,我们将不胜感激。

谢谢, 拉贾拉姆

首先,请注意存储在密码字段中的值不仅仅是最终的哈希值,还包括算法、每个用户的加盐值和最终的哈希值(均由 $ 符号分隔)。所以,假设我们有:

stored_password = 'pbkdf2(1000,20,sha512)$b787f1e6dfe7da8f$b280b42a152aa14a1944d35c6a070521251b85d1'

首先做如下事情:

_, salt, hashed_password = stored_password.split('$')

现在,因为使用了 pbkdf2,我们必须使用 hashlib.pbkdf2_hmac 来比较哈希:

from hashlib import pbkdf2_hmac
entered_password = 'MyPassword'
is_match = hashed_password == pbkdf2_hmac('sha512', entered_password, salt,
                                          rounds=1000, dklen=20).encode('hex')

或者,如果您不介意将 web2py validators.py 模块复制到其他系统,您可以简单地执行以下操作:

from validators import CRYPT
is_match = CRYPT()(entered_password)[0] == stored_password

注意,CRYPT() 是一个可调用对象(就像所有的 web2py 验证器一样)。当您使用输入的密码调用它时,它 returns 一个元组,其第一个元素是一个 LazyCrypt 对象。 LazyCrypt class 实现了它自己的 __eq__ 特殊方法,所以上面的 == 比较触发了那个方法。它自动从 stored_password 中提取摘要算法、salt 和散列,计算 entered_password 的散列,并将其与从 stored_password 中提取的散列进行比较(即,在上面的解决方案)。