如何使用Python加密1GB以上大文件?Fernet分段解密报错如何解决?
大文件Fernet加密解密错误解决方案
错误根因
你的推测完全正确:Fernet每次加密生成的都是独立、完整的token,必须完整读取才能完成签名校验和解密。你加密时输入4096字节明文,输出的加密token长度会大于4096字节,解密时每次读取4096字节无法拿到完整的加密token,自然触发签名校验失败、抛出InvalidToken错误。
现有逻辑修复方案
你只需要调整分片读写逻辑,让解密端可以准确识别每个加密块的边界即可,推荐用预写块长度的方案实现,稳定不会出问题:
加密侧代码
from cryptography.fernet import Fernet import struct key = Fernet(read_key()) # 明文分片大小可自行调整,建议设置为32KB/64KB降低IO频次 PLAIN_CHUNK_SIZE = 64 * 1024 with open(source, "rb") as src, open(destination, "wb") as dest: for chunk in iter(lambda: src.read(PLAIN_CHUNK_SIZE), b""): encrypted_chunk = key.encrypt(chunk) # 用2字节无符号短整型存储当前加密块的长度,最大支持65535字节的加密块,完全满足需求 dest.write(struct.pack("<H", len(encrypted_chunk))) dest.write(encrypted_chunk)
解密侧代码
from cryptography.fernet import Fernet import struct key = Fernet(read_key()) with open(source, "rb") as src, open(destination, "wb") as dest: while True: # 先读取2字节获取当前加密块长度 len_raw = src.read(2) if not len_raw: break chunk_len = struct.unpack("<H", len_raw)[0] # 读取完整加密块后再解密 encrypted_chunk = src.read(chunk_len) decrypted_chunk = key.decrypt(encrypted_chunk) dest.write(decrypted_chunk)
更简单的大文件加密方案
如果不想自己处理分片逻辑,有两种更简单的选择:
- 直接使用cryptography库官方提供的
FernetCipher流式加密接口,已经内置了大文件分片处理逻辑,无需自行处理块边界,代码更简洁不易出错 - 改用
pycryptodome库的AES-GCM模式做流式加密,性能比Fernet更高,内存占用可以稳定控制在几十KB级别,非常适合GB级大文件加密,也不需要处理复杂的分片边界逻辑
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

