使用Fernet在Python脚本中加密成功但解密失败求助
问题原因分析
你的解密失败核心有两个问题:
- 加密结果的类型处理偏差:加密函数返回的是
bytes对象,但当你把DataFrame保存为文件(比如CSV)或在传输/读取过程中,pandas会自动把bytes转成字符串形式的bytes表示(即类似"b'gAAAAABnCRr1...'"的字符串),而非保留原始bytes类型。 - 解密函数逻辑错误:你在解密时调用了
field_value.encode(),这会导致:- 如果field_value是原始
bytes对象:调用encode()会触发异常,直接走except分支返回原值; - 如果field_value是字符串形式的bytes:
encode()会把这个字符串转成字节码(比如把"b'xxx'"变成b"b'xxx'"),这根本不是加密后的原始bytes,解密自然失败,最终返回原值。
- 如果field_value是原始
解决方案
根据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
相关产品推荐
相关产品推荐

