在登录路径上,我检索密码。我如何在数据库中找到具有匹配的哈希密码的用户而不获取整个用户表并在服务器上遍历它?
在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表并在服务器端进行遍历。但是我想在数据库端遍历!如何使用bcrypt哈希方法完成此任务?
答案 0 :(得分:1)
现代安全加密为每个用户分配一个唯一的盐(随机字符串),以便如果某个用户(例如Alice)注册到您的网站并使用密码“ password”,那么将为她分配的哈希数据库条目为:< / p>
Hash("password" + "random_string_for_alice") = "HASH_VALUE:MD51000:random_string_for_alice"
此处的哈希字符串包括哈希算法(MD5)x1000迭代和所使用的盐(“ random_string_for_alice”)
现在,如果仅向您提供密码-仅密码而不是用户名-为了找出它属于谁(如果有)的用户名,您将必须查看每个用户的哈希密码,提取公共密码并应用迭代,然后进行比较。您将需要对数据库中的每个用户执行此操作以找到答案。
这当然是现代密码加密建议的重点。
答案 1 :(得分:0)
bcrypt的整个工作方式是,它为您提供了一个值,该值将哈希密码和salt组合为一个值供您存储。
这意味着您不能使用没有盐的盐重新创建密码中的哈希值。
您需要通过可能具有的user_id
从数据库中选择用户,然后使用bcrypt库将您的密码与您存储的组合值进行比较。
bcrypt.hashpw(password, hash_and_salt_value_from_db)
您可以使用与创建“哈希”相同的函数,但是传入您的存储值。该功能非常聪明,可以认识到它是一个哈希+盐,将为您提取和使用盐。
所以您想检查
if hash_and_salt_value_from_db == bcrypt.hashpw(password, hash_and_salt_value_from_db):
# tada, valid password
如果这没有意义,请大声喊叫。