Oracle 21c编译加密PL/SQL包出现PLS-00201错误:DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT/DESDECRYPT未声明(Oracle 18c可正常运行)
解决Oracle 21c中
DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT/DESDECRYPT未声明的编译错误 别担心,这个问题我帮你分析清楚了,还准备了适配的解决方案:
错误原因
Oracle在版本迭代中逐步淘汰了旧的加密API,DBMS_OBFUSCATION_TOOLKIT里的DESENCRYPT和DESDECRYPT方法早在12c就被标记为废弃,到21c版本直接移除了这些函数,所以你的代码在21c环境下编译时会找不到这些标识符,触发PLS-00201错误。
解决方法
Oracle官方推荐使用更安全、功能更完善的DBMS_CRYPTO包作为替代方案,它支持包括DES在内的多种加密算法,并且在新版本中持续维护。下面是修改后的适配21c的PL/SQL包体代码:
create or replace package body encryption as -- DES算法要求密钥长度为8字节(单DES),这里从原密钥截取前8位,你也可以自定义合适的8字节密钥 key_string raw(16) := UTL_RAW.cast_to_raw(SUBSTR('$0@!H&^%#8I^~!JYE&#$55JKH*(@#$^^',1,8)); encrypted_string raw(2048); decrypted_string varchar2(2048); -- 自定义填充函数,和原逻辑对齐(用*填充到8的倍数) function pad(input_string IN varchar2) return varchar2 is len number; pad_len number; begin len := LENGTH(input_string); pad_len := 8 - MOD(len,8); if pad_len !=8 then return input_string || RPAD('*',pad_len,'*'); else return input_string; end if; end; function encrypt (input_string IN varchar2) return raw is BEGIN encrypted_string := DBMS_CRYPTO.ENCRYPT( src => UTL_RAW.cast_to_raw(pad(input_string)), typ => DBMS_CRYPTO.DES_CBC_PKCS5, -- 这里用CBC模式+PKCS5填充,也可以根据需求调整 key => key_string, iv => UTL_RAW.cast_to_raw('12345678') -- CBC模式需要初始化向量,这里自定义8字节IV ); RETURN encrypted_string; END; function decrypt(input_string In raw) RETURN varchar2 IS BEGIN decrypted_string := UTL_RAW.cast_to_varchar2( DBMS_CRYPTO.DECRYPT( src => input_string, typ => DBMS_CRYPTO.DES_CBC_PKCS5, key => key_string, iv => UTL_RAW.cast_to_raw('12345678') ) ); RETURN RTRIM(decrypted_string,'*'); END; END; /
关键注意点
- 权限配置:需要确保你的数据库用户拥有
EXECUTE权限,执行以下语句授权:GRANT EXECUTE ON DBMS_CRYPTO TO your_username; - 密钥与IV规范:DES算法要求密钥长度严格为8字节,CBC模式下的初始化向量(IV)也需要8字节,加密和解密时必须使用完全相同的密钥和IV才能正常解密。
- 数据类型适配:
DBMS_CRYPTO的加密结果为RAW类型,比原代码的VARCHAR2更适合存储加密数据,如果需要转换为字符串展示或存储,可以使用UTL_RAW.CAST_TO_VARCHAR2或RAWTOHEX函数处理。
内容的提问来源于stack exchange,提问作者om mahesh
相关产品推荐
相关产品推荐

