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

PostgreSQL解密函数无法输出明文:编码解码问题排查

问题描述

我通过AES-ECB加密实现Python/Django与PostgreSQL间的数据加解密,已知CBC模式更优,但数据库已完成静态加密,本次操作仅用于对部分员工数据做模糊处理。

Python加密代码如下:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64

enc_secret = AES.new(settings.AES_KEY.encode("utf-8"), AES.MODE_ECB)
cipher_text = base64.b64encode(enc_secret.encrypt(pad(value.encode('utf-8'), AES.block_size)))

加密后的邮箱示例存储在PostgreSQL的bytea类型字段中(列头显示为Text)。直接执行以下SQL可正常获取明文:

select decrypt(decode('vqRkrhUW9ze4Id0qSYHg0g==','BASE64'),'key','aes-ecb')

但通过列名调用解密时出现错误:

select
    email, decrypt(decode(email::text,'base64')::bytea,
        'key',
        'aes-ecb')

    from table

报错信息:[22023] ERROR: invalid symbol "\" while decoding base64 sequence

请问编码解码环节哪里出现了问题?


问题原因与解决办法

核心原因

PostgreSQL将bytea类型转换为text时,会自动添加转义符(比如反斜杠),导致你拿到的text并非原始Base64字符串,而是带转义的格式,因此decode操作会识别到非法的反斜杠字符,触发报错。

解决方法

方法1:直接使用bytea字段进行解密

decrypt函数的第一个参数本身就接受bytea类型,而你的字段刚好是bytea类型,无需多余的encode/decode步骤,直接传入字段名即可:

select
    email, decrypt(email, 'key', 'aes-ecb')
from table;

方法2:正确转换bytea为Base64字符串

如果确实需要先转Base64,不要用::text强制转换,改用encode(email, 'base64')直接从bytea生成标准Base64字符串:

select
    email, decrypt(decode(encode(email, 'base64'), 'base64'),
        'key',
        'aes-ecb')
from table;

补充说明

你的Python代码中,base64.b64encode返回的是二进制bytes数据,存储到bytea字段时PostgreSQL会直接保存该二进制内容。但用email::text转换时,PostgreSQL会把bytea转为带转义的十六进制/文本表示(例如\x7671526b72685557397a6534496430715359486730673d3d),这显然不是原始的Base64字符串,才会导致解码失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 11:49:51