使用Python Fernet库解密文件时触发ValueError密钥格式报错
报错原因
这个报错触发的直接原因是传入Fernet()构造函数的密钥不符合格式要求:Fernet只接受32字节随机值经url-safe base64编码后得到的44字节长度bytes类型密钥,你当前读取到的thekey.key文件内容不满足这个规范,90%的场景是以下问题导致:
- 写加密程序时,文件遍历的排除列表没加
thekey.key,运行加密程序时把密钥文件本身也加密了,解密时读取到的是加密后的密文,不是原始密钥 - 写入密钥文件时用了文本模式
"w"而非二进制模式"wb",导致密钥编码被转义损坏 - 解密程序运行的工作目录不对,读取到的
thekey.key不是本次加密生成的对应密钥,是其他目录下的同名无关文件
排查与修复方法
- 先验证密钥合法性
在读取密钥的代码后加两行调试代码,确认密钥状态:
正常合法的Fernet密钥长度固定为44字节,内容是随机的url-safe base64字符,结尾通常带1-2个print("读取到的密钥长度:", len(secretkey)) print("读取到的密钥内容:", secretkey)=补位符。如果长度不对,直接说明密钥已经损坏,最常见的就是被加密程序误加密了——这种情况如果没有原始密钥备份,被加密的文件无法恢复,Fernet采用的AES128-CBC+HMAC认证没有暴力破解的可能性。 - 修正加密程序逻辑
加密程序遍历文件时,必须把密钥文件、加密脚本、解密脚本加入排除列表,绝对不能加密密钥文件;写入密钥时必须用二进制写入模式"wb",避免编码损坏。 - 替换为带校验的解密代码
下面的代码增加了密钥格式校验、解密异常捕获,避免因为单个文件损坏导致整个程序崩溃:#!/usr/bin/python3 import os from cryptography.fernet import Fernet, InvalidToken files = [] # 收集待解密文件,跳过程序和密钥文件 for file in os.listdir(): if file in ("voldemort.py", "thekey.key", "decrypt.py"): continue if os.path.isfile(file): files.append(file) print("待解密文件列表:", files) # 读取密钥 with open("thekey.key", "rb") as f: secretkey = f.read() # 校验密钥格式 if len(secretkey) != 44: raise RuntimeError("密钥格式非法,确认thekey.key是加密时生成的原始文件,未被加密或损坏") cipher = Fernet(secretkey) for file in files: with open(file, "rb") as f: encrypted_data = f.read() try: decrypted_data = cipher.decrypt(encrypted_data) except InvalidToken: print(f"跳过文件 {file}:密钥不匹配或文件已损坏") continue with open(file, "wb") as f: f.write(decrypted_data) print("解密流程执行完毕")
内容的提问来源于stack exchange,提问作者Lorenzo
相关产品推荐
相关产品推荐

