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

Fernet同密钥解密后文件为空 原因及加密内容恢复方法

问题描述

我在加密逻辑中生成密钥,使用Fernet(key).encrypt(contents)对文件内容进行加密。后续使用同一密钥调用Fernet(key).decrypt(contents)解密内容时,所有文件内容被清空,加密后的文件变为空文件。
加密代码如下:

root_dir = "test_dir"
all_files = []

for file in os.listdir(root_dir):
    if os.path.isfile(os.path.join(root_dir, file)):
        all_files.append(os.path.join(root_dir, file))

key = Fernet.generate_key()
with open("key.key", "wb") as keyfile:
    keyfile.write(key)

for file in all_files:
    with open(file, "wb+") as raw_file:
        contents = raw_file.read()
        enc_contents = Fernet(key).encrypt(contents)
        raw_file.write(enc_contents)

解密代码如下:

with open("key.key", "rb") as thekey:
    code = thekey.read()

for file in all_files:
    with open(file, "rb") as enc_file:
        contents = enc_file.read()
    raw_contents = Fernet(code).decrypt(contents)
    print("Raw contents: ", raw_contents)
    with open(file, "wb") as enc_file:
        enc_file.write(raw_contents)
问题原因

问题根源在加密代码的文件打开模式:

  • 加密环节使用wb+模式打开目标文件,该模式触发时会立即清空文件全部原有内容,后续执行read()读取到的本身就是空值,你加密的对象从一开始就是空字节,最终写回文件的加密内容对应的就是空数据。
  • 解密代码的逻辑本身没有错误,只是因为待解密的文件存的本来就是空内容的加密结果,解密后自然得到空值,写回后文件就保持为空,和密钥是否匹配没有关系。
数据恢复结论

原有文件内容无法通过代码手段恢复。
使用wb+打开文件的瞬间,文件系统就已经将原文件占用的存储块标记为可覆写状态,后续写入的空内容加密结果已经覆盖了原有数据的存储位置,没有办法通过常规手段找回。如果磁盘没有发生大量后续写入,可尝试使用专业磁盘数据恢复工具扫描残留碎片,但成功率无法保证,不属于代码可解决的范畴。

正确写法修正

后续做文件加解密操作时,必须将读、写操作拆分,禁止使用会提前截断文件的模式打开待读取的原文件:

  • 加密时先以只读rb模式打开文件,将全部内容读取到内存完成加密计算后,再以wb模式打开文件写入加密结果,避免同一文件句柄读写导致的内容提前丢失。更稳妥的方式是先将加密结果写入临时文件,校验无误后再替换原文件。
    修正后的加密代码片段:
for file in all_files:
    # 第一步:只读模式读取原文件内容,不会修改文件
    with open(file, "rb") as raw_file:
        contents = raw_file.read()
    # 内存中完成加密计算
    enc_contents = Fernet(key).encrypt(contents)
    # 第二步:写入模式打开文件,此时再覆盖原内容
    with open(file, "wb") as raw_file:
        raw_file.write(enc_contents)
  • 对重要文件执行加解密操作前,必须先做全量备份,避免代码逻辑错误导致不可逆的数据丢失。

内容的提问来源于stack exchange,提问作者Chinmay Chhajed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:24:31