使用Bcrypt hashpw/checkpw时认证失败:加密密码不匹配求助
问题
在基于db.Model的Python User类中,使用Bcrypt的hashpw和checkpw实现用户注册加密存储密码及登录认证功能时,注册阶段已成功将加盐哈希后的密码存入数据库,但登录时对比用户输入与存储密码始终返回false导致认证失败。排除依赖问题,复用了之前成功实现的代码仍无法定位错误,相关代码如下:
注册类方法
@classmethod def signup(cls, username, email, image_url, password): """Sign up user. Hashes password and adds user to system. """ byte_pwd = password.encode('utf-8') my_salt = bcrypt.gensalt() hashed_pwd = bcrypt.hashpw(byte_pwd,my_salt) user = User( username=username, email=email, image_url=image_url, password=hashed_pwd ) db.session.add(user) db.session.commit() return user
认证类方法
@classmethod def authenticate(cls, username, password): """Find user with `username` and `password`""" user = cls.query.filter_by(username=username).first() print(user) print(user.password.encode('utf-8')) byte_pwd = password.encode('utf-8') my_salt = bcrypt.gensalt() hashed_pwd = bcrypt.hashpw(byte_pwd, my_salt) if user: is_auth = bcrypt.checkpw(user.password.encode('utf-8'), hashed_pwd) if is_auth: return user return False
解决方案
错误原因
认证方法存在两个关键错误:
- 无意义地重新生成盐并计算哈希值——Bcrypt的哈希结果本身已包含盐,无需额外存储盐,更不需要重新生成盐做对比。
checkpw参数顺序完全颠倒:正确顺序是用户输入的明文密码(字节形式)在前,数据库存储的哈希密码(字节形式)在后。
修正后的认证方法
@classmethod def authenticate(cls, username, password): """Find user with `username` and `password`""" user = cls.query.filter_by(username=username).first() if user: byte_pwd = password.encode('utf-8') # 按正确参数顺序调用checkpw:明文字节在前,数据库存储的哈希字节在后 is_auth = bcrypt.checkpw(byte_pwd, user.password.encode('utf-8')) if is_auth: return user return False
额外说明
- 注册阶段代码无需修改,
bcrypt.hashpw生成的哈希值已包含盐,直接存入数据库即可。 - 无需手动存储盐,Bcrypt会自动从哈希值中提取盐完成密码验证。
内容的提问来源于stack exchange,提问作者Sean.realitytester
相关产品推荐
相关产品推荐

