Python SHA256加密数据类型问题 数据库取回哈希值校验报错
首先纠正一个常见误区:passlib 库的 pwd_context.verify() 原生支持字符串类型的合法哈希值入参,“数据库返回的哈希是字符串类型”本身不是报错原因,报错核心是你取到的哈希值和加密时生成的原始哈希不匹配,或是密码上下文配置不一致,按以下步骤逐一排查修复即可:
检查存储哈希的数据库字段长度
passlib 基于 SHA256 生成的带盐哈希字符串长度约为 70~80 字符,如果你设置的varchar字段长度小于这个值,哈希值存库时会被截断,残缺的哈希自然无法通过校验。请将对应字段长度修改为varchar(255),同时清空之前被截断的旧哈希数据,重新生成加密后存入。校验存取过程中哈希值的一致性
在调用加密函数拿到返回值准备存库前,打印原始哈希值;再打印从数据库查询取回的哈希值,逐字符对比。如果取回的值存在前后空格、多余引号、转义斜杠这类冗余内容,传入校验函数前先做清理:def decrypt(password, hashed): # 清除存取过程中意外带上的冗余字符 valid_hash = hashed.strip().strip("'\"").replace("\\", "") return pwd_context.verify(str(password), valid_hash)确认加密、校验环节的 pwd_context 配置完全一致
初始化CryptContext时指定的算法、参数必须在加密和校验逻辑中保持完全相同,否则会出现哈希格式无法识别的报错。标准初始化参考如下,加密和校验逻辑要复用同一个配置的实例:from passlib.context import CryptContext # 加密、校验必须使用相同配置的pwd_context实例 pwd_context = CryptContext(schemes=["sha256_crypt"], deprecated="auto") def encrypt(password): return pwd_context.hash(str(password)) def decrypt(password, hashed): valid_hash = hashed.strip().strip("'\"").replace("\\", "") return pwd_context.verify(str(password), valid_hash)检查数据库连接的字符集配置
连接 MySQL 时必须指定字符集为utf8mb4,避免哈希中的特殊字符在存取过程中被转码损坏,以 pymysql 为例的连接写法:import pymysql conn = pymysql.connect( host="数据库地址", user="用户名", password="数据库密码", database="库名", charset="utf8mb4" )
注意:不要手动将取回的字符串哈希强行转成 bytes 类型,该操作反而会破坏哈希格式,触发新的校验报错。
内容的提问来源于stack exchange,提问作者Anij Mehta

