You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 12:00:51