问题描述
因此,我最近学习了如何将密码存储在数据库中,即通过向明文密码添加盐,对其进行散列,然后存储散列。我在解释器中做了一个小实验
>>>从os导入urandom
>>>盐= urandom(32).encode('base-64')
>>> salt
'+ 3DejJpQZO9d8campsxOB6fam6lBE0mJ / + UvFf3oG8c = \ n'
>>> plaintext_pw ='archer'
>>> plaintext_pw
'archer'
>>>> salted_pw = plaintext_pw + salt
>>> salted_pw
$ archer + 3DejJpQZO9d8campsxOB6fam6lBE0mJ / + UvFf3oG8c = \\\
'
>>> from flaskext.bcrypt import Bcrypt
>>> bc = Bcrypt(None)
>>> hashed_pw = bc.generate_password_hash(salted_pw)
>>>> hashed_pw
'$ 2a $ 12 $ znMwqAw.GliVE8XFgMIiA.aEGU9iEZzZZWfxej5wSUFP0huyzdUfe'
现在一切正常,但是当我转身时他:
>>> bc.generate_password_hash(plaintext_pw + salt)
'$ 2a $ 12 $ qbywkEjuJgmBvXW6peHzAe.rWjoc.ybFKRNzuZhom2yJSXaMRcVTq'
'$ 2a $ 12 $ FAh9r4oaD40mWPtkClAnIOisP37eAT5m.i.EGV1zRAsPNbxg3BlX2'
>>> bc.generate_password_hash(plaintext_pw + salt)
'$ 2a $ 12 $ gluk9RUiR6D0e2p1J.hNgeE3iTFxDUlCNvFJOsCZZk89ngO.Z6 / B6'
据我可以告诉plaintext_pw和盐在调用之间不改变。我似乎无法发现这里的错误,有人可以向我解释到底发生了什么,我做错了什么?
好吧,看起来我已经解决了我的问题。原来我没有正确使用bcrypt。下面是我所学到的:
每次我调用generate_password_hash时,哈希都是不同的,因为bcrypt会自动为您生成一个salt并将其附加到哈希密码,所以不需要生成它与urandom或分开存放。
我没有在我的帖子中谈论过这个,不过在这里值得注意 - 我假设在登录时需要调用generate_password_hash()并提供密码从登录表单创建第二个散列check_password_hash()进行比较,但这不是必需的。 check_password_hash()可以使用存储的散列和表单密码(分别)调用,它将自动处理表单密码的哈希和散列,并将其与存储的散列进行比较。
现在一切正常。希望这可以帮助别人!
So I've recently learned how to store passwords in a DB, that is by adding a salt to the plaintext password, hashing it, and then storing the hash.
I'm working on a really small Flask app to try all this out, but I'm having a problem with the password hashing and checking parts of the process. It seems that I"m ending up with two different hashes for the same input and I can't seem to figure out why.
I ran a little experiment in the interpreter to test things out.
>>> from os import urandom
>>> salt = urandom(32).encode('base-64')
>>> salt
'+3DejJpQZO9d8campsxOB6fam6lBE0mJ/+UvFf3oG8c=\n'
>>> plaintext_pw = 'archer'
>>> plaintext_pw
'archer'
>>> salted_pw = plaintext_pw + salt
>>> salted_pw
'archer+3DejJpQZO9d8campsxOB6fam6lBE0mJ/+UvFf3oG8c=\n'
>>> from flaskext.bcrypt import Bcrypt
>>> bc = Bcrypt(None)
>>> hashed_pw = bc.generate_password_hash(salted_pw)
>>> hashed_pw
'$2a$12$znMwqAw.GliVE8XFgMIiA.aEGU9iEZzZZWfxej5wSUFP0huyzdUfe'
All is working well at this point, but when I turn around and do this:
>>> bc.generate_password_hash(plaintext_pw + salt)
'$2a$12$qbywkEjuJgmBvXW6peHzAe.rWjoc.ybFKRNzuZhom2yJSXaMRcVTq'
I get a completely different hash, even though I started with the same plaintext_pw and salt. I thought that wasn't supposed to happen? Furthermore each subsequent call to bc.generate_password_hash() gives me different results each time:
>>> bc.generate_password_hash(plaintext_pw + salt)
'$2a$12$FAh9r4oaD40mWPtkClAnIOisP37eAT5m.i.EGV1zRAsPNbxg3BlX2'
>>> bc.generate_password_hash(plaintext_pw + salt)
'$2a$12$gluk9RUiR6D0e2p1J.hNgeE3iTFxDUlCNvFJOsCZZk89ngO.Z6/B6'
As far as I can tell plaintext_pw and salt aren't changing between calls. I can't seem to spot the error here, could someone explain to me exactly what's happening here, and what it is I'm doing wrong?
Ok so it looks like I've solved my problem. Turns out I wasn't using bcrypt properly. Here's what I learned:
The hashes were different each time I called generate_password_hash because bcrypt automatically generates a salt for you and appends it to the hashed password, so no need to generate it with urandom or store it separately.
I didn't talk about this in my post, but its worth noting here anyway - I assumed that on login you would need to call generate_password_hash() and provide the password from the login form to create a second hash for check_password_hash() to compare against, but that isn't necessary. check_password_hash() can be called with the stored hash and the form password (respectively) and it will automatically take care of salting and hashing the form password, and comparing it to the stored hash.
And with that everything is working fine now. Hope this helps someone else!
这篇关于使用flask-bcrypt生成和验证密码哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!