Python Pickle文件HMAC认证签名无效问题排查求助
问题原因分析及修复方案
核心错误点
- 签名与数据的分隔逻辑错误:写入时直接将签名字节拼接在数据前,未添加分隔符(如换行符),但读取时用
f.readline()读取签名——readline()会读取到换行符或文件末尾,而文件中无换行符,导致读取的digest是整个文件内容,data为空,后续签名验证必然失败。 - 签名读取方式错误:HMAC的
hexdigest()输出是固定长度字符串(blake2b默认128个字符),应读取固定长度字节作为签名,而非依赖换行符的readline()。 - 编码与依赖问题:写入代码未导入
sys模块,直接使用sys.stdin.encoding会触发NameError;且依赖环境编码转换签名字节存在不确定性,易导致字节差异。
修复后的代码
写入代码
import sys import pickle import hashlib import hmac # 示例数据定义(你的原有代码) df1 = pd.DataFrame({'id' : [1,2,3,4,5], 'score' : [720, 700, 710, 690, 670]}) df2 = pd.DataFrame({'name' : ['abc', 'pqr', 'xyz'], 'address' : ['1st st', '2nd ave', '3rd st'] }) mylist = ['a', 'b', 'c', 'd', 'e'] mydict = {1 : 'p', 2 : 'q', 3 : 'r'} obj = [df1, df2, mylist, mydict] data = pickle.dumps(obj) digest = hmac.new(b'unique-key-here', data, hashlib.blake2b).hexdigest() with open('temp.txt', 'wb') as output: # 用utf-8编码签名,添加换行符分隔签名与数据 output.write(digest.encode('utf-8') + b'\n' + data)
读取验证代码
import hmac import hashlib import pickle with open('temp.txt', 'rb') as f: # 读取签名行并去除末尾换行符 digest = f.readline().strip() data = f.read() recomputed = hmac.new(b'unique-key-here', data, hashlib.blake2b).hexdigest() # 使用hmac自带的compare_digest做安全对比 if not hmac.compare_digest(digest, recomputed.encode('utf-8')): print('Invalid signature') else: print('Signature matching') # 验证通过后加载数据 obj = pickle.loads(data)
额外注意事项
- 确保读写时密钥
b'unique-key-here'完全一致,必须是字节类型(不能用字符串)。 - 固定使用
utf-8编码转换签名,避免环境编码差异导致的验证失败。 - 生产环境中使用pickle需谨慎,仅加载可信来源的文件,防止代码注入风险。
内容的提问来源于stack exchange,提问作者Karthik S
相关产品推荐
相关产品推荐

