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

使用Fernet在Python脚本中加密成功但解密失败求助

问题原因分析

你的解密失败核心有两个问题:

  1. 加密结果的类型处理偏差:加密函数返回的是bytes对象,但当你把DataFrame保存为文件(比如CSV)或在传输/读取过程中,pandas会自动把bytes转成字符串形式的bytes表示(即类似"b'gAAAAABnCRr1...'"的字符串),而非保留原始bytes类型。
  2. 解密函数逻辑错误:你在解密时调用了field_value.encode(),这会导致:
    • 如果field_value是原始bytes对象:调用encode()会触发异常,直接走except分支返回原值;
    • 如果field_value是字符串形式的bytes:encode()会把这个字符串转成字节码(比如把"b'xxx'"变成b"b'xxx'"),这根本不是加密后的原始bytes,解密自然失败,最终返回原值。
解决方案

根据DataFrame中加密值的实际类型,选择对应的修正方式:

情况1:加密后未保存,DataFrame中仍是原始bytes对象

直接修改解密函数,去掉多余的encode():

import os
from cryptography.fernet import Fernet
from dotenv import load_dotenv

load_dotenv()
secret_key = os.getenv('secret_key')
fernet_out = Fernet(secret_key)

def decrypt_field(field_value):
    try:
        # 直接用原始bytes解密,再转成字符串
        return fernet_out.decrypt(field_value).decode()
    except Exception as e:
        return field_value

# 应用解密
transactions['titre'] = transactions['titre'].apply(decrypt_field)
transactions['titre_origine'] = transactions['titre_origine'].apply(decrypt_field)

情况2:加密后已保存/读取,值变成了字符串形式的bytes(如"b'gAAAAA...'")

需要先把字符串解析回原始bytes,再解密:

import os
import ast
from cryptography.fernet import Fernet
from dotenv import load_dotenv

load_dotenv()
secret_key = os.getenv('secret_key')
fernet_out = Fernet(secret_key)

def decrypt_field(field_value):
    try:
        # 先把字符串形式的bytes解析为原始bytes
        if isinstance(field_value, str):
            field_value = ast.literal_eval(field_value)
        # 解密并转成字符串
        return fernet_out.decrypt(field_value).decode()
    except Exception as e:
        return field_value

# 应用解密
transactions['titre'] = transactions['titre'].apply(decrypt_field)
transactions['titre_origine'] = transactions['titre_origine'].apply(decrypt_field)

额外建议:加密时统一转成字符串存储

为避免bytes类型在DataFrame存储/传输中被自动转换,建议加密时直接把bytes转成字符串,存储和传输更稳定:

# 修改加密函数
def encrypt_data(field_value):            
    try:
        # 加密后转成字符串,而非保留bytes
        return fernet_out.encrypt(field_value.encode()).decode()
    except Exception as e:
        return field_value

对应的解密函数可直接处理字符串:

def decrypt_field(field_value):
    try:
        # 把字符串转成bytes再解密
        return fernet_out.decrypt(field_value.encode()).decode()
    except Exception as e:
        return field_value

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:57:07