遍历数据库端的表以比较bcrypt散列的密码

kcugc4gi  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(331)

在登录路径上,我检索密码。如何在数据库中找到具有匹配哈希密码的用户,而不获取整个用户表并在服务器上遍历它?
在mysql中,每个用户注册时都有一个哈希密码。我是这样生成的: bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') 如果我在登录时执行相同的方法(对于相同的纯文本密码),我会得到不同的哈希值。
比如说:

select * from User where hash_generated_at_register = hash_generated_at_login

失败,即使登录和注册步骤中使用的纯文本密码相同。
据我所知,bcrypt中的密码检查是由 bcrypt.checkpw(password, hash) 而不是再次散列。使用这种方法,我能想到的唯一选项是选择整个user表并在服务器端传递它。但我想在db端进行遍历!如何使用bcrypt散列方法实现这一点?

luaexgnf

luaexgnf1#

现代安全加密为每个用户分配一个唯一的salt(随机字符串),这样,如果某个用户(比如alice)登录到您的网站并使用密码“password”,那么将为她分配的哈希数据库条目是:

Hash("password" + "random_string_for_alice") = "HASH_VALUE:MD51000:random_string_for_alice"

这里的散列字符串包括散列算法(md5)x1000次迭代和使用的salt(“random \u string \u for \u alice”)
现在,如果您只提供了一个密码-只有一个密码,而不是用户名-为了找出它属于谁(如果有的话)的用户名,您必须查看每个用户的散列密码,提取公共salt并应用迭代,然后进行比较。您需要为数据库中的每个用户执行此操作才能找到答案。
当然,这就是现代密码加密建议的重点。。

83qze16e

83qze16e2#

bcrypt的整个工作方式是,它为您提供一个值,该值将哈希密码和salt组合成一个值供您存储。
这意味着您无法在没有salt的情况下从密码重新创建哈希,而salt是您所没有的。
您需要通过一些 user_id 然后使用bcrypt库将密码与存储的组合值进行比较。

bcrypt.hashpw(password, hash_and_salt_value_from_db)

您可以使用与创建“哈希”相同的函数,但可以传入存储值。这个函数足够聪明,可以意识到它是一个hash+salt,并将为您提取和使用salt。
所以你想检查一下

if hash_and_salt_value_from_db == bcrypt.hashpw(password, hash_and_salt_value_from_db):
    # tada, valid password

如果说不通就大声喊。

相关问题