当我检查密码时,bcrypt 中的盐无效
Invalit salt in bcrypt when i checkpw
使用烧瓶 python。
当我尝试比较用 bcrypt.hashpw() 加密的散列密码时
说无效盐。
现在我测试它,如果我把这个 if 语句 wok 但只有在 html 表单的密码字段中我粘贴密码散列(问题是我需要输入普通密码)
所以比较我确定 html 中的表单字段并且连接到数据库以获取用户密码仅在我需要输入 bcrypt.checkpw(password_in_the_login_form.html, password_hashed_in_the_db 时失败)
每次都说 Invalid Salt,这里是我的代码:
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = '01b0cfa6c076da9264d7ea8b44967445'
app.config['MYSQL_DB'] = 'flaskdb'
app.config['MYSQL_CURSORCLASS'] = 'DictCursor'
mysql = MySQL(app)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form['Email']
password = request.form['Password']
curl = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
curl.execute("SELECT * FROM users WHERE Email=%s",(email,))
user = curl.fetchone()
if len(user) > 0:
if user["Password"] == password:
session['Email'] = email
session['Nickname'] = user["Nickname"]
return render_template("profile.html")
else:
return "Error password and email not match"
else:
return "Error user not found"
else:
return render_template("login.html")
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for("home"))
@app.route("/signup", methods=["GET", "POST"])
def signup():
if request.method == 'GET':
return render_template("signup.html")
else:
nickname = request.form['Nickname']
firstName = request.form['First_Name']
lastName = request.form['Last_Name']
email = request.form['Email']
password = request.form['Password'].encode('utf-8')
hash_password = bcrypt.hashpw(password, bcrypt.gensalt(14))
cur = mysql.connection.cursor()
cur.execute("INSERT INTO users (Nickname, First_Name, Last_Name,
Email, Password) VALUES (%s,%s,%s,%s,%s)",(nickname,firstName,lastName,email,hash_password,))
mysql.connection.commit()
return redirect(url_for('home'))
if __name__ == '__main__':
app.secret_key = 'bb8ef1d0a8de0bf09b4b2aaee861a7d5'
app.run(debug=True)
和 html 形式
<form action="/signup" method="POST">
<input type="text" class="form-field" name="Nickname" placeholder="Nickname">
<input type="text" class="form-field" name="First_Name" placeholder="First Name">
<input type="text" class="form-field" name="Last_Name" placeholder="Last Name">
<input type="email" class="form-field" name="Email" placeholder="Email">
<input type="password" class="form-field" name="Password" placeholder="Password">
<button type="submit" class="signup-btn">SIGNUP</button>
</form>
<form action="/login" method="POST">
<input type="email" class="form" name="Email"><br>
<input type="password" class="form" name="Password"><br>
<button type="submit" class="login-btn">LOGIN</button>
</form>
很难准确找出问题所在,因为我们缺少 MCVE 和 错误跟踪 ,无论如何我们至少可以猜测可能是什么原因.
虚线
首先,你在这一行有问题:
password = b'password'
您从未存储任何用户密码,而是它们都已被 password
值覆盖。在您的函数中注释掉这一行,您将能够存储用户输入的密码而不是虚拟值。
很遗憾,由于您丢失了原始用户信息,因此无法恢复已存储的密码。
工作流程
然后我们可以确认bcrypt
按预期工作:
import bcrypt
saltp = bcrypt.gensalt(14) # b'bQmgF.1F4dTKeb8o8dprEu'
hashp = bcrypt.hashpw('abcdef'.encode(), saltp) # b'bQmgF.1F4dTKeb8o8dprEuo2T2Y908hdZan9fb.LDWDuibPl/SLpm'
bcrypt.checkpw('abcdef'.encode(), hashp) # True
从上面的这个片段,你应该尝试你的过程的所有步骤(添加 MySQL I/O 和新密码)以突出显示导致问题的步骤:
- 在客户端使用区域设置收集的密码 (
str
);
- 在服务器端使用 bcrypt (
bytes
) 对密码进行哈希处理;
- 存储在 MySQL 中的密码哈希(受第一个错误的影响,我们仍然不知道您存储它的类型,是否必须 escaped,请阅读评论)
- 从 MySQL 检索到密码哈希;
- 使用 bcrypt 将密码哈希与用户输入进行比较;
危险
我的猜测: 问题出在 Flask 和 MySQL 之间,因为转换问题 bytes
(BLOB
) 与 str
(TEXT
)。这很可能是您必须使用 user["Password"].encode('utf-8')
进行调整的原因,但它可能引入了另一个错误,因为您没有转义散列密码:您可能需要转义散列密码,因为 您正在尝试在文本字段中存储二进制数据.
我的建议: 在密码流程的每一步,检查 password/hash 值并确认您正在处理您认为的内容。当出现差异时,您将确定错误的来源。如果您仍然需要帮助,请在 POST 中明确描述。
谢谢,但这(我认为)正是我所拥有的。
我不知道为什么我有错误 我有 .hashpw 对密码进行哈希处理并将其存储在数据库中,这没关系,我看到数据库中的密码已加密,但是 .checkpw 用于将表单中的密码与密码进行比较在数据库中失败,说 Invalit salt 代码正是这样比较:
if bcrypt.checkpw(password, userPassworddb):
其中 password 是用户在登录表单中已经输入的密码 .encode('utf-8') 和 userPassworddb 是数据库中加密的密码(也需要转换 userPassworddb.encode('utf-8') 因为如果我不这样做,调试器会说我需要在比较之前进行编码)
在 html 的登录中,我有这个:
<form action="/login" method="POST">
<input type="email" class="form" name="Email"><br>
<input type="password" class="form" name="Password"><br>
<button type="submit" class="login-btn">LOGIN</button>
</form>
使用烧瓶 python。 当我尝试比较用 bcrypt.hashpw() 加密的散列密码时 说无效盐。
现在我测试它,如果我把这个 if 语句 wok 但只有在 html 表单的密码字段中我粘贴密码散列(问题是我需要输入普通密码) 所以比较我确定 html 中的表单字段并且连接到数据库以获取用户密码仅在我需要输入 bcrypt.checkpw(password_in_the_login_form.html, password_hashed_in_the_db 时失败) 每次都说 Invalid Salt,这里是我的代码:
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = '01b0cfa6c076da9264d7ea8b44967445'
app.config['MYSQL_DB'] = 'flaskdb'
app.config['MYSQL_CURSORCLASS'] = 'DictCursor'
mysql = MySQL(app)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form['Email']
password = request.form['Password']
curl = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
curl.execute("SELECT * FROM users WHERE Email=%s",(email,))
user = curl.fetchone()
if len(user) > 0:
if user["Password"] == password:
session['Email'] = email
session['Nickname'] = user["Nickname"]
return render_template("profile.html")
else:
return "Error password and email not match"
else:
return "Error user not found"
else:
return render_template("login.html")
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for("home"))
@app.route("/signup", methods=["GET", "POST"])
def signup():
if request.method == 'GET':
return render_template("signup.html")
else:
nickname = request.form['Nickname']
firstName = request.form['First_Name']
lastName = request.form['Last_Name']
email = request.form['Email']
password = request.form['Password'].encode('utf-8')
hash_password = bcrypt.hashpw(password, bcrypt.gensalt(14))
cur = mysql.connection.cursor()
cur.execute("INSERT INTO users (Nickname, First_Name, Last_Name,
Email, Password) VALUES (%s,%s,%s,%s,%s)",(nickname,firstName,lastName,email,hash_password,))
mysql.connection.commit()
return redirect(url_for('home'))
if __name__ == '__main__':
app.secret_key = 'bb8ef1d0a8de0bf09b4b2aaee861a7d5'
app.run(debug=True)
和 html 形式
<form action="/signup" method="POST">
<input type="text" class="form-field" name="Nickname" placeholder="Nickname">
<input type="text" class="form-field" name="First_Name" placeholder="First Name">
<input type="text" class="form-field" name="Last_Name" placeholder="Last Name">
<input type="email" class="form-field" name="Email" placeholder="Email">
<input type="password" class="form-field" name="Password" placeholder="Password">
<button type="submit" class="signup-btn">SIGNUP</button>
</form>
<form action="/login" method="POST">
<input type="email" class="form" name="Email"><br>
<input type="password" class="form" name="Password"><br>
<button type="submit" class="login-btn">LOGIN</button>
</form>
很难准确找出问题所在,因为我们缺少 MCVE 和 错误跟踪 ,无论如何我们至少可以猜测可能是什么原因.
虚线
首先,你在这一行有问题:
password = b'password'
您从未存储任何用户密码,而是它们都已被 password
值覆盖。在您的函数中注释掉这一行,您将能够存储用户输入的密码而不是虚拟值。
很遗憾,由于您丢失了原始用户信息,因此无法恢复已存储的密码。
工作流程
然后我们可以确认bcrypt
按预期工作:
import bcrypt
saltp = bcrypt.gensalt(14) # b'bQmgF.1F4dTKeb8o8dprEu'
hashp = bcrypt.hashpw('abcdef'.encode(), saltp) # b'bQmgF.1F4dTKeb8o8dprEuo2T2Y908hdZan9fb.LDWDuibPl/SLpm'
bcrypt.checkpw('abcdef'.encode(), hashp) # True
从上面的这个片段,你应该尝试你的过程的所有步骤(添加 MySQL I/O 和新密码)以突出显示导致问题的步骤:
- 在客户端使用区域设置收集的密码 (
str
); - 在服务器端使用 bcrypt (
bytes
) 对密码进行哈希处理; - 存储在 MySQL 中的密码哈希(受第一个错误的影响,我们仍然不知道您存储它的类型,是否必须 escaped,请阅读评论)
- 从 MySQL 检索到密码哈希;
- 使用 bcrypt 将密码哈希与用户输入进行比较;
危险
我的猜测: 问题出在 Flask 和 MySQL 之间,因为转换问题 bytes
(BLOB
) 与 str
(TEXT
)。这很可能是您必须使用 user["Password"].encode('utf-8')
进行调整的原因,但它可能引入了另一个错误,因为您没有转义散列密码:您可能需要转义散列密码,因为 您正在尝试在文本字段中存储二进制数据.
我的建议: 在密码流程的每一步,检查 password/hash 值并确认您正在处理您认为的内容。当出现差异时,您将确定错误的来源。如果您仍然需要帮助,请在 POST 中明确描述。
谢谢,但这(我认为)正是我所拥有的。 我不知道为什么我有错误 我有 .hashpw 对密码进行哈希处理并将其存储在数据库中,这没关系,我看到数据库中的密码已加密,但是 .checkpw 用于将表单中的密码与密码进行比较在数据库中失败,说 Invalit salt 代码正是这样比较:
if bcrypt.checkpw(password, userPassworddb):
其中 password 是用户在登录表单中已经输入的密码 .encode('utf-8') 和 userPassworddb 是数据库中加密的密码(也需要转换 userPassworddb.encode('utf-8') 因为如果我不这样做,调试器会说我需要在比较之前进行编码)
在 html 的登录中,我有这个:
<form action="/login" method="POST">
<input type="email" class="form" name="Email"><br>
<input type="password" class="form" name="Password"><br>
<button type="submit" class="login-btn">LOGIN</button>
</form>