实现方式:先把字段AES加密,再转为BASE64格式,再转成字符串存储,双重加密字段,解密则相反,先将字段值转换为BASE64格式,进行BASE64解密,再进行AES解密。
*方法一(此方法有问题,会与java如AES-128-ECB加密出来的密文不一致,哪怕协议一样也不一样,请参考方法二):
一、所用到内置函数:
1.SELECT * FROM V$CIPHERS --查询支持的加密方式
2.CFALGORITHMSDECRYPT('加密值',第一步查询的加密方式id,'自定义密匙') -- AES加密函数
3.CFALGORITHMSDECRYPT('解密值',第一步查询的加密方式id,'自定义密匙') -- AES解密函数
4.UTL_ENCODE.BASE64_ENCODE('加密值') --BASE64加密函数
5.UTL_ENCODE.BASE64_DECODE('解密值') --BASE64解密函数
6.UTL_RAW.CAST_TO_RAW('值') --将字符串转为BASE64格式
7.UTL_RAW.CAST_TO_VARCHAR2('值') --将BASE64格式转为字符串格式
二、进行加密操作sql:
UPDATE 表名 SET USERNAME = UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(CFALGORITHMSENCRYPT(字段名,513,'密匙') ))
-- 解析:这里先进行AES加密操作,再进行BASE64加密操作,此处使用`AES128_ECB`格式加密,
-- 则对应`SELECT * FROM V$CIPHERS`语句查询出来的CYT_ID = 513,因为最后加密出来是
-- BASE64格式,长度太大,所以通过`UTL_RAW.CAST_TO_VARCHAR2` 函数转为字符串进行存储
三、进行解密/模糊查询操作sql:
SELECT * FROM SYS_USER WHERE CFALGORITHMSDECRYPT(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(字段名)),513,'密匙') like '%值%'
-- 解析:此处先把字段通过`UTL_RAW.CAST_TO_RAW`转为BASE64格式进行解密,再进行AES解密
-- ,最终将得到的明文值进行模糊查询
*方法二(在与达梦技术人员沟通后,得到以下方法):
前提(需要使用到sys
目录下的DBMS_CRYPTO
包内的函数):
1.执行SELECT id_code;
,得到版本号,此方法需要最低版本应该在20230417
版本左右,反正尽量新,不然会报:-2193: 第1 行附近出现错误:无效的方法名[ENCRYPT]
类似的找不到函数的问题
2.如果版本够新依旧报找不到函数,则使用SYSDBA相同权限的用户分别执行SP_CREATE_SYSTEM_PACKAGES (0,'DBMS_CRYPTO')
;和SP_CREATE_SYSTEM_PACKAGES (1,'DBMS_CRYPTO');
,重新下载此包。
3.检验该版本是否有此包,使用SYSDBA相同权限用户执行:
SELECT PROCEDURE_NAME FROM ALL_PROCEDURES WHERE OWNER = 'SYS'
AND OBJECT_NAME = 'DBMS_CRYPTO'
- 若版本没有此包则显示如下信息:
- 有此包则显示如下信息(才能正常使用该功能):
4.在满足上述正常条件下,加密时执行(注:进行加密的字段值不能为null,否则会报:SQL 错误 [22000]: 非法的参数数据
):
SELECT
BINTOCHAR (
UTL_ENCODE.BASE64_ENCODE (
DBMS_CRYPTO.ENCRYPT(
UTL_I18N.STRING_TO_RAW ( 字段名, 'UTF8' ),
DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5,
UTL_I18N.STRING_TO_RAW ( '密匙', 'UTF8' )
)
)
) from dual;
5.在满足上述正常条件下,解密时执行(注:进行解密的字段值不能为null或不是上部加密格式的密文,否则会报:SQL 错误 [22000]: 非法的参数数据
):
SELECT
UTL_I18N.RAW_TO_CHAR (
DBMS_CRYPTO.DECRYPT (
UTL_ENCODE.BASE64_DECODE (
CHARTOBIN ( 字段名)),
DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5,
UTL_I18N.STRING_TO_RAW ( '密匙', 'UTF8' )
),
'UTF8'
) FROM dual WHERE 字段名 IS NOT NULL
--或把DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5写成529效果一样
6.模糊查询时:
select * from dual where (字段 is not null and (
UTL_I18N.RAW_TO_CHAR (
DBMS_CRYPTO.DECRYPT (
UTL_ENCODE.BASE64_DECODE (
CHARTOBIN ( 字段名)),
DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5,
UTL_I18N.STRING_TO_RAW ( '密匙', 'UTF8' )
),
'UTF8'
)
) like '%值%' ;