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

使用functools.partial迭代解密文件时触发cryptography.fernet.InvalidToken错误

使用Fernet分段解密时触发InvalidToken错误的修复方案

问题背景

用functools.partial迭代读写文件做加解密,加密函数encryypt()运行正常,但解密decryypt()时抛出cryptography.fernet.InvalidToken错误,已确认密钥和Fernet实例一致,问题出在迭代读写的逻辑上。

原代码

key = Fernet.generate_key()
print(key)
cypher = Fernet(key)


def encryypt():
    with open('file.pdf', 'rb') as f, open('file2.pdf', 'wb') as target_f: 
        for _bytes in iter(partial(f.read, 10*2048), ''):
            encrypt_data = cypher.encrypt(_bytes)
            target_f.write(encrypt_data)
            if not _bytes:break
    target_f.close()

def decryypt() :
    with open('file2.pdf', 'rb') as ff, open('file3.pdf', 'wb') as target_ff: 
        for __bytes in iter(partial(ff.read, 10*2048), ''):
            decrypt_data = cypher.decrypt(__bytes)
            target_ff.write(decrypt_data)
            if not __bytes:break
encryypt()
decryypt()

报错信息

Traceback (most recent call last):
  File "C:\Users\#\#\.venv\Lib\site-packages\cryptography\fernet.py", line 134, in _verify_signature
    h.verify(data[-32:])
cryptography.exceptions.InvalidSignature: Signature did not match digest.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\Users\#\#\Bin2\Start\test.py", line 43, in <module>
    decryypt()
  File "c:\Users\#\#\Bin2\Start\test.py", line 39, in decryypt
    decrypt_data = cypher.decrypt(__bytes)
                   ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\#\#\.venv\Lib\site-packages\cryptography\fernet.py", line 91, in decrypt
    return self._decrypt_data(data, timestamp, time_info)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\#\#\.venv\Lib\site-packages\cryptography\fernet.py", line 152, in _decrypt_data
    self._verify_signature(data)
  File "C:\Users\#\#\.venv\Lib\site-packages\cryptography\fernet.py", line 136, in _verify_signature
    raise InvalidToken
cryptography.fernet.InvalidToken

问题根源

  1. 哨兵值类型不匹配:iter(partial(f.read, ...), '')中,二进制文件读取返回bytes类型,哨兵用字符串''永远不会匹配,导致循环多处理一次空字节块,写入无效加密数据。
  2. Fernet Token完整性被破坏:Fernet加密后的每个结果是独立的、格式固定的Token,不能拆分或拼接后解密。原代码解密时按固定字节数读取,会把多个Token混在一起或截断单个Token,导致decrypt()无法识别有效签名,抛出InvalidToken。

修复方案

修改加解密逻辑,确保每个加密后的Token单独存储(用换行分隔,Fernet Token不含换行符),解密时按完整Token读取:

from cryptography.fernet import Fernet
from functools import partial

key = Fernet.generate_key()
print(key)
cypher = Fernet(key)


def encryypt():
    with open('file.pdf', 'rb') as f, open('file2.pdf', 'wb') as target_f:
        # 二进制读取的哨兵值改为b'',匹配返回类型
        for _bytes in iter(partial(f.read, 10*2048), b''):
            if not _bytes:
                break
            encrypt_data = cypher.encrypt(_bytes)
            # 每个Token后写入换行符分隔
            target_f.write(encrypt_data + b'\n')

def decryypt():
    with open('file2.pdf', 'rb') as ff, open('file3.pdf', 'wb') as target_ff:
        # 按行读取每个完整的Token
        for line in ff:
            token = line.strip()
            if not token:
                continue
            decrypt_data = cypher.decrypt(token)
            target_ff.write(decrypt_data)

encryypt()
decryypt()

关键修改点

  • 加密时将哨兵值改为b'',避免处理无效空字节块。
  • 每个加密Token后添加换行符,保证Token的独立性。
  • 解密时按行读取,去除换行符后再解密,确保传入decrypt()的是完整有效的Fernet Token。

内容的提问来源于stack exchange,提问作者Ninja-Flex6969

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:22:45