使用flask-bcrypt生成和验证密码哈希 [英] Generating and verifying password hashes with flask-bcrypt

查看:211
本文介绍了使用flask-bcrypt生成和验证密码哈希的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我最近学习了如何将密码存储在数据库中,即通过向明文密码添加盐,对其进行散列,然后存储散列。



<我正在研究一个非常小的Flask应用程序来尝试所有这些,但我有一个密码散列和检查过程的一部分的问题。看来,我结束了两个不同的哈希相同的投入,我似乎无法弄清楚为什么。

我在解释器中做了一个小实验

 >>>从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'



<我得到了一个完全不同的散列,即使我开始使用相同的plaintext_pw和盐。我以为这不应该发生?此外,每次随后对bc.generate_password_hash()的调用都会给我不同的结果: 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'

据我可以告诉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生成和验证密码哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆