解密文件时触发cryptography.fernet.InvalidToken错误,求排查
解决
cryptography.fernet.InvalidToken错误:加密解密密钥不匹配问题 问题根源
你的代码核心问题是加密时用的密钥和保存到文件的密钥不是同一个:
- 调用
create_key_file()时,生成了一个密钥写入key.key文件; - 但调用
encrypt_file()时,又重新调用generate_key()生成了新的密钥,用这个新密钥加密了文件; - 解密时读取的是
key.key里的旧密钥,自然无法解密新密钥加密的内容,触发InvalidToken错误。
修复方案
调整加密器逻辑,确保加密和保存密钥用的是同一个值,有两种可行方式:
方式1:生成一次密钥,同时用于保存和加密
修改Encrypter类,让密钥只生成一次,复用在保存和加密流程中:
from cryptography.fernet import Fernet class Encrypter: def __init__(self, key_path, data_path): self.key_path = key_path self.data_path = data_path self.key = None # 存储生成的密钥 def generate_key(self): self.key = Fernet.generate_key() return self.key def create_key_file(self): if not self.key: self.generate_key() with open(self.key_path, 'wb') as keyfile: keyfile.write(self.key) def encrypt_file(self): if not self.key: self.generate_key() fernet = Fernet(self.key) with open(self.data_path, 'rb') as tf: tf_bytes = tf.read() tf_bytes_enc = fernet.encrypt(tf_bytes) with open(self.data_path, 'wb') as tf: tf.write(tf_bytes_enc) # 使用示例 key_obj = Encrypter(key_path='key.key', data_path='sample_file.csv') key_obj.create_key_file() key_obj.encrypt_file()
方式2:加密时读取已保存的密钥
如果希望先保存密钥,再用该密钥加密,修改encrypt_file方法读取已生成的密钥:
from cryptography.fernet import Fernet class Encrypter: def __init__(self, key_path, data_path): self.key_path = key_path self.data_path = data_path def generate_key(self): return Fernet.generate_key() def create_key_file(self): key = self.generate_key() with open(self.key_path, 'wb') as keyfile: keyfile.write(key) def get_key(self): with open(self.key_path, 'rb') as keyfile: return keyfile.read() def encrypt_file(self): key = self.get_key() fernet = Fernet(key) with open(self.data_path, 'rb') as tf: tf_bytes = tf.read() tf_bytes_enc = fernet.encrypt(tf_bytes) with open(self.data_path, 'wb') as tf: tf.write(tf_bytes_enc) # 使用示例 key_obj = Encrypter(key_path='key.key', data_path='sample_file.csv') key_obj.create_key_file() key_obj.encrypt_file()
解密器代码(可保持不变)
你的解密器逻辑本身没问题,只要加密时密钥统一,解密就能正常运行:
from cryptography.fernet import Fernet class Decrypter: def __init__(self, key_path, data_path): self.key_path = key_path self.data_path = data_path def get_key(self): with open(self.key_path, 'rb') as keyfile: key = keyfile.read() return key def open_encrypted_file(self): with open(self.data_path, 'rb') as tf: tf_bytes = tf.read() fernet = Fernet(self.get_key()) tf_bytes_dec = fernet.decrypt(tf_bytes) return tf_bytes_dec def decrypt_file(self): with open(self.data_path, 'wb') as tf: tf.write(self.open_encrypted_file()) return tf # 使用示例 key_obj = Decrypter(key_path='key.key', data_path='sample_file.csv') key_obj.decrypt_file()
内容的提问来源于stack exchange,提问作者CUI
相关产品推荐
相关产品推荐

