bcrypt.checkpw验证异常求助:正确密码返回False
问题根源
你的问题出在SQLite字段类型与bcrypt哈希存储格式不匹配:
- 注册时,
bcrypt.hashpw生成的是bytes类型的哈希值,但你直接将其插入到TEXT类型的password字段中。Python的sqlite3模块会把bytes对象转换为它的字符串表示(比如b'$2b$14...'),而非解码为原始的哈希字符串,导致数据库中存储的哈希是带b'前缀和'后缀的错误格式。 - 登录时,即使取出的内容被转为
bytes类型,实际是b"b'$2b$14...'",和原始哈希完全不匹配,因此bcrypt.checkpw返回False。
解决方案
有两种可行的修复方式,选其一即可:
方式1:将哈希解码为字符串后存储(无需修改表结构)
修改注册函数,把bytes类型的哈希解码为UTF-8字符串再插入数据库:
# 注册函数中修改哈希部分 bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt(14)).decode('utf-8')
然后修改登录函数,取出字符串哈希后再编码为bytes传给checkpw:
# 登录函数中验证部分 if bcrypt.checkpw(password.encode('utf-8'), hashed_password[0].encode('utf-8')): return True
方式2:修改数据库字段为BLOB类型(更贴合bytes存储)
既然bcrypt哈希本质是字节数据,直接将password字段类型改为BLOB,这样插入和读取都是原生bytes,无需编码转换:
修改表结构中的password字段:
password BLOB NOT NULL,
注意:修改表结构后,需要重新创建表(或用ALTER TABLE修改现有表),并且之前注册的用户需要重新注册(因为旧的错误格式哈希无法使用)。
验证建议
修复后,你可以先手动验证:
- 用正确的方式生成哈希:
bcrypt.hashpw(b'test101', bcrypt.gensalt(14)).decode('utf-8'),得到纯哈希字符串。 - 对比数据库中存储的哈希值,确认是纯字符串(无
b'包裹)。 - 再调用
bcrypt.checkpw(b'test101', 哈希字符串.encode('utf-8')),应该返回True。
内容的提问来源于stack exchange,提问作者Sergio Razo
相关产品推荐
相关产品推荐

