解密文件行时触发cryptography.fernet.InvalidToken错误求助
问题根源与修复方案
你的InvalidToken错误主要来自加密数据写入时的格式错误,再加上读取逻辑的小问题,导致解密时拿到的不是有效的Fernet令牌。下面逐点说明问题和修复:
1. 加密数据写入的核心错误
在add分支里,你把加密后的字节对象直接转成字符串:
enc_line_str = str(enc_line)
比如加密后的字节是b'gAAAAABk...',转成字符串后会变成"b'gAAAAABk...'"——这个字符串包含了b'前缀和'后缀,完全不是Fernet能识别的令牌格式。
修复方式:
Fernet令牌本身是Base64编码的,可以直接解码成UTF-8字符串保存(推荐),或者直接以二进制模式写入文件:
# 把加密后的字节解码成字符串(Fernet令牌兼容UTF-8) enc_line_str = enc_line.decode('utf-8') # 写入时加换行符,避免所有数据挤在一行 with open("passwords.data", "a", encoding='utf-8') as outfile: outfile.write(enc_line_str + '\n')
2. 读取文件的逻辑错误
在view分支里有几个小问题:
- 第一次
line = infile.readline()后,进入循环立刻又执行line = infile.readline(),直接跳过了文件的第一行数据。 - 循环条件
while line != ""不对,二进制模式下readline()返回的是字节对象,空值应该是b""。 - 解密后转字符串用
str(line_dec)会得到"b'xxx yyy'",应该用decode('utf-8')得到正常的文本字符串。
修复后的view分支代码:
if cmd == "view": found = False search = input("Name to search for: ") # 对应文本模式保存的密码文件,用r模式打开 with open("passwords.data", "r", encoding='utf-8') as infile: # 逐行读取,避免跳过第一行 for line in infile: line = line.strip() # 去掉换行符和空白 if not line: continue try: # 文本模式读取的字符串,转成字节再解密 line_dec = fernet.decrypt(line.encode('utf-8')) line_dec_str = line_dec.decode('utf-8') except Exception as e: print(f"解密失败:{e}") continue if search in line_dec_str: found = True print(line_dec_str) if not found: print("Error: name not found in file. Try again.")
额外建议
- 尽量用
with语句操作文件,它会自动帮你关闭文件,避免忘记close()导致的资源泄漏。 - 解密时加上异常捕获,避免单个无效行导致整个程序崩溃。
内容的提问来源于stack exchange,提问作者cb879
相关产品推荐
相关产品推荐

