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

Django中AESSIV加密数据解密异常:无法还原明文问题排查

无法解密数据库中加密数据的问题排查与解决

核心问题原因

问题出在加密后的数据类型处理不当:

  • encrypt_field函数返回的是base64.b64encode()的结果,这是一个bytes对象。存入Django的CharField时,Django会自动将其转换为字符串表示,也就是类似"b'CSPex4eChMQ...'"的格式(包含b'前缀和'后缀)。
  • 解密时,input_text是这个带b''包裹的字符串,调用base64.b64decode()会因非法字符(b'和')抛出异常,导致decrypt_field直接返回原输入字符串,也就是你看到的错误结果。

解决方案

方案1:加密时返回Base64字符串(推荐,适配CharField/TextField)

修改encrypt_field函数,将Base64编码后的bytes转换为UTF-8字符串,确保存入数据库的是纯Base64文本,无多余的b''包裹:

def encrypt_field(input_text):
    try:
        if isinstance(input_text, str):
            input_text = input_text.encode()
        enc_text = cipher_suite.encrypt(input_text, associated_data = None)
        enc_text_base_64 = base64.b64encode(enc_text)
        # 将bytes转换为字符串后返回
        return enc_text_base_64.decode('utf-8')
    
    except Exception as e:
        error_logger.error(f"exception in encrypt field {str(e)} on field {input_text}")
        return input_text

修改后存入数据库的是纯Base64字符串,解密时input_text为正常字符串,base64.b64decode()可正确解析,最终返回明文。

方案2:使用BinaryField存储原始加密字节

若坚持用BinaryField存储,需调整加密解密流程,跳过Base64编码(BinaryField直接存储bytes):

修改加密函数
def encrypt_field(input_text):
    try:
        if isinstance(input_text, str):
            input_text = input_text.encode()
        # 直接返回加密后的bytes,跳过Base64编码
        return cipher_suite.encrypt(input_text, associated_data = None)
    
    except Exception as e:
        error_logger.error(f"exception in encrypt field {str(e)} on field {input_text}")
        return input_text
修改解密函数
def decrypt_field(input_text):
    try:
        # BinaryField读取的是bytes,直接解密
        decrypted_field = cipher_suite.decrypt(input_text, associated_data = None)
        return decrypted_field.decode('utf-8')
    
    except Exception as e:
        print(e)
        error_logger.error(f"exception in decrypt_field {e} on field {input_text}")
        return input_text
同步修改Model字段
class User(AbstractUser):
    username = models.BinaryField(unique=True)
    email = models.BinaryField(unique=True)
    # 其他字段保持不变...

额外验证步骤

  1. 清理数据库中已有的错误格式数据(带b''的字符串),重新加密存入。
  2. 单独测试加密解密流程:调用encrypt_field("redgrave@example.com")确认返回纯字符串,再传入decrypt_field验证是否能得到原明文。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:12:32