我有一个包含三列的表
id username password
----------------------
1 Jdoe $2a$12$sv97wrhscHkKVMZ8P/2yw.O/cz8pWUE/1zlTyFNJ9.jCYhR8Nw9Iu
2 user $2a$12$dLeSlYFyPdP1WhA4Tw21ZuX5v5XH55.yK2XApMd4VglUDRJEd4Lmy
我的目标是根据登录时提供的密码对用户进行身份验证。为此,我编写了如下代码的Python代码:
from bcrypt import hashpw, gensalt
if request.method == 'POST':
if form.validate() == False:
return render_template('login.html', form = form)
else:
#return render_template('index.html')
password = request.form['password']
password = hashpw(password, gensalt())
con = sql.connect("testDB.db")
cur = con.cursor()
cur.execute("SELECT * FROM mytable where password =?", (password,))
if cur.fetchall():
return "welcome guest"
else:
return "user not found"
但是,当我输入现有密码时,系统会返回“未找到用户”消息。所需的输出是“欢迎客人”消息。hashpw
和gensalt()
是从bcrypt
导入的。
我很确定我错误地定义了变量“password”。如何正确定义这样的变量?
答案 0 :(得分:1)
您正在生成一个新哈希,一个具有完全不同的盐:
password = hashpw(password, gensalt())
您无法通过密码查找用户;使用salted哈希的重点是让黑客无法使用彩虹表(常用密码哈希,但没有盐)来匹配哈希值。同样的保护使您无法预先了解给定用户使用的盐,并且几乎可以保证您可以从新盐中生成不同的哈希值。
您需要使用用户名立即查找,检索已添加盐渍的密码,然后让bcrypt.checkpw()
功能安全地测试密码存储的哈希。哈希值包含salt,bcrypt
将提取salt并使用它来验证是否生成了相同的哈希。比较需要防止定时攻击,不要自己重新执行此检查。
您的表单需要发送用户名,而不仅仅是密码:
from bcrypt import checkpw
username = request.form['username']
password = request.form['password']
con = sql.connect("testDB.db")
cur = con.cursor()
cur.execute("SELECT password FROM mytable where username = ?", (username,))
hashed = cur.fetchone()
if hashed is None or not checkpw(password, hashed[0]):
# no such user, *or* the password did not match
return "user not found"
# password matched the hashed value from the database
return "welcome guest"