散列密码与Python中的原始密码不匹配

时间:2018-01-07 05:15:28

标签: python hash passlib

我有两个休息端点,一个用于注册用户,另一个用于登录用户。这是我用来散列用户密码并将散列密码存储在数据库中的代码,

from passlib.hash import pbkdf2_sha256
def _get_hashed_password(self, password):
    return pbkdf2_sha256.encrypt(password, rounds=200000, salt_size=16)

现在在登录端点上,我使用此代码验证散列密码

password = data['password']
hash = pbkdf2_sha256.encrypt(password, rounds=200000, salt_size=16)
pbkdf2_sha256.verify(user.hashed_password, hash)

这种方法失败并且很明显,因为两个密码不同,

$pbkdf2-sha256$200000$ai0FoDTG2BuDkDKGEIJQKg$Ik06dr61.2rRMDwZCZMdVq.zMe5887.ksDxvmSXFRwE
$pbkdf2-sha256$200000$pHTuHYNwLoXQeu8dI0QoxQ$2z4cZl9Njz9X/bxNtWCZzzeplWO.jTZA2v5lvcmgFE8

我想知道如何才能让它发挥作用?

1 个答案:

答案 0 :(得分:5)

pbkdf2_sha256.encryptpbkdf2_sha256.verify不只是计算密码的哈希值。仔细查看pbkdf2_sha256.encrypt

的输出
$pbkdf2-sha256$200000$ai0FoDTG2BuDkDKGEIJQKg$Ik06dr61.2rRMDwZCZMdVq.zMe5887.ksDxvmSXFRwE
----------------------------------------------------------------------------------------
$  algorithm  $rounds$         salt         $             the actual hash

您可以在几年内切换算法,增加轮数,pbkdf2_sha256.verify仍然可以根据数据库中存储的哈希验证明文密码。

两次使用相同的密码不会每次都给出相同的结果,因为使用了随机盐。如果攻击者获得密码哈希值,则盐会阻止rainbow table attacks。基本上,您不是仅计算hash(password),而是计算类似hash(salt + password)的内容。由于盐已经在上面的字符串中给出,你可能知道密码,你也会知道salt + password的价值,你的生活将不再困难。但对于花费大量时间预先计算hash(password)的攻击者而言,这些哈希值都不会有用,因为它们不包含随机盐。

与评论中发布的示例一样,您无需执行任何特殊操作来验证密码:

pbkdf2_sha256.verify(password, user.hashed_password)

验证密码时无需拨打pbkdf2_sha256.encryptpbkdf2_sha256.verify为您完成所有这些。