PostgreSQL 9.6转12迁移:pgcrypto rijndael_decrypt兼容问题求助
解决PostgreSQL迁移至RDS时自定义rijndael_decrypt函数兼容问题
问题核心
你使用的rijndael_decrypt并非标准pgcrypto扩展的函数,而是基于自定义C扩展pg_rijndael实现的,其加密/解密逻辑与RDS PG12自带的pgcrypto v1.3标准函数不匹配,导致解密时报"数据不是块大小倍数"错误。
解决方案步骤
1. 明确自定义函数的加密逻辑细节
在原PG9.6环境中执行以下操作,获取关键参数:
- 查看密钥的字节长度(确定AES密钥位数):
结果对应:16字节=AES-128,24字节=AES-192,32字节=AES-256。SELECT length(convert_to('你的测试密钥', 'utf8')); - 用现有数据验证逻辑:
提取原库中已知明文对应的密文和密钥,用于后续RDS上的测试:SELECT 明文字段, 密文字段, 密钥字段 FROM 你的业务表 LIMIT 1;
2. 在RDS PG12中创建兼容的包装函数
根据原函数的参数结构(key为text,input为bytea,返回text),推测其核心逻辑为:将text密钥转成UTF8编码的bytea,用AES(Rijndael)ECB模式解密,解密结果转成UTF8 text。在RDS中创建对应包装函数:
CREATE OR REPLACE FUNCTION public.rijndael_decrypt(key text, input_text bytea) RETURNS text LANGUAGE sql STRICT AS $$ -- 根据实际密钥长度替换aes-256为aes-128/aes-192 SELECT convert_from( decrypt(input_text, convert_to(key, 'utf8'), 'aes-256-ecb/pkcs7'), 'utf8' ); $$;
3. 解决"数据不是块大小倍数"报错
如果仍报该错误,尝试以下调整:
- 更换填充方式:将
pkcs7改为none(仅当原加密未使用填充时),但此时密文必须是16字节倍数,需手动处理填充字节。 - 检查模式:如果原函数使用CBC模式(可能内置固定IV),则需要找到原IV后调整函数:
SELECT convert_from( decrypt(input_text, convert_to(key, 'utf8'), 'aes-256-cbc/pkcs7', '\x你的固定IV字节值'), 'utf8' );
4. 备选方案:使用RDS Custom部署原扩展
如果上述模拟逻辑无法匹配,且你使用的是RDS Custom(允许安装自定义C扩展),可以将原pg_rijndael扩展的代码编译后部署到RDS Custom实例中,实现完全兼容。
内容的提问来源于stack exchange,提问作者Marcin Zareba
相关产品推荐
相关产品推荐

