generate_password_hash & check_password_hash

Flask 中的加盐哈希加密算法

目录

前言

开发中必经的用户登录模块中,通常为了用户的隐私安全,存在数据库中的密码都是经过加密的,这也是常识。密码存储无非就是分为两种,明文存储(裸奔😐)与加密存储,而加密存储就是通过一定的对原始密码进行变换,从而使密码原文不容易被识别。

而密码加密通常有如下算法:

Flask 中的密码加密和解密(验证)

一般会使用 flask 中的 generate_password_hash()check_password_hash() 进行加密和解密,使用之前先从 werkzeug 库中导入:

from werkzeug.security import generate_password_hash, check_password_hash

generate_password_hash()

函数原型

其中这个函数最重要的就是里面的三个参数,generate_password_hash(password, method="pbkdf2:sha256", salt_length=16)

一般如果不改变加密方式或者盐值长度可直接调用函数传入第一个参数即可,即传入你要加密的明文密码;一般加密强度选择默认已经足够了,如果想要更加强的加密,则改变盐值长度和迭代次数即可,最后生成的 hash 值格式如下:

method$salt$hash

check_password_hash

函数原型

generate_password_hash() 所对应的,在写验证密码是否一致的逻辑时可用到,check_password_hash(pwhash, password) 两个参数:

需要注意:check_password_hash() 返回的是布尔值。

实例

一般这两个函数会同时使用,用来检测用户输入的登录密码与数据库是否一致;下面给出视图函数中的一个实例,模板文件就不给出了,就是从表单中获取到用户的用户名、密码;

# 注册
@user_bp1.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
repassword = request.form.get('repassword')
phone = request.form.get('phone')
email = request.form.get('email')
if password == repassword:
# 注册用户
user = User()
user.username = username
# 使用自带的函数实现加密
user.password = generate_password_hash(password)
user.phone = phone
user.email = email
# 添加并提交
db.session.add(user)
db.session.commit()
return redirect(url_for('user.index'))
return render_template('user/register.html')
# 用户登录
@user_bp1.route('/login', methods=['GET','POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
users = User.query.filter(User.username == username).all()
for user in users:
# 如果 flag 为 true 表示匹配,否则密码不匹配;
flag = check_password_hash(user.password, password)
if flag:
return '用户登录成功!'
else:
return render_template('user/login.html', msg='用户名或者密码有误')
return render_template('user/login.html')

有些细节没有完善,只需要关注这两个函数的用处;User 是所定义的用户模型,这里还是要提醒一下:由于加密后的字段长度会很大,所以一开始设置模型的时候就应该把字段值设置的大一点,这里我设置了:password = db.Column(db.String(150),nullable=False) ,经过验证是足够使用的。

另外也附上这两个函数的简单调用实例:

from werkzeug.security import generate_password_hash, check_password_hash
# 明文密码
password = 'this_is_a_password'
# 生成加密哈希值
password_hash = generate_password_hash(password)
print(password_hash)
# 验证密码(正确)
is_true = check_password_hash(password_hash, password)
print(is_true)
# 验证密码(错误)
is_true1 = check_password_hash(password_hash, "there_are_many_passwords")
print(is_true1)

结果如下:

简单实例结果

参考