DBMS_CRYPTO属于SYS模式且未向PUBLIC授权,普通用户需SYS AS SYSDBA显式授予EXECUTE权限并严格使用SYS.DBMS_CRYPTO调用,参数须为RAW类型且符合算法要求。

DBMS_CRYPTO属于SYS模式,不是PUBLIC对象
Oracle从10g起就把DBMS_CRYPTO包放在SYS模式下,且未向PUBLIC授予EXECUTE权限。这意味着:普通用户即使有DBA角色,也无法跨模式直接调用它——这不是权限不足,而是Oracle的访问控制模型决定的。
常见错误是执行:GRANT EXECUTE ON DBMS_CRYPTO TO myuser;,结果报ORA-00942: table or view does not exist,因为没写SYS.前缀;或者报ORA-01917: user or role 'MYUSER' does not exist,实则是用户名大小写不匹配(比如用双引号建过"MyUser")。
必须用SYS AS SYSDBA身份显式授权
只有SYS用户(或具备ADMIN OPTION的授权者)能跨模式授出SYS.DBMS_CRYPTO的权限。普通DBA账号执行会失败,哪怕已连上数据库。
- 正确操作必须是:
CONNECT / AS SYSDBA;,再执行GRANT EXECUTE ON SYS.DBMS_CRYPTO TO myuser; - 不能省略
SYS.——写成DBMS_CRYPTO会被解析为当前模式下的同名对象(不存在) - 目标用户必须已存在,且名称大小写与授权语句严格一致(Oracle默认大写,双引号创建的需带引号)
PL/SQL里调用时仍要加SYS前缀
即使授权成功,在PL/SQL块中直接写DBMS_CRYPTO.ENCRYPT(...)仍会报PLS-00201: identifier 'DBMS_CRYPTO' must be declared。
原因:PL/SQL作用域不自动搜索SYS模式,必须显式指定:
- 加密:
SYS.DBMS_CRYPTO.ENCRYPT(src => ..., typ => ..., key => ...) - 哈希:
SYS.DBMS_CRYPTO.HASH(src => ..., typ => DBMS_CRYPTO.HASH_MD5) - 生成密钥:
SYS.DBMS_CRYPTO.RANDOMBYTES(32)
漏掉SYS.是运行时最常踩的坑,和授权是否成功无关。
授权后仍可能报密钥或IV错误
权限只是第一步。后续调用失败往往和参数类型、长度、编码强相关:
-
src、key、iv都必须是RAW类型,不能传VARCHAR2字面量 - AES-256要求密钥长度为32字节:
UTL_I18N.STRING_TO_RAW('my256bitkey...', 'AL32UTF8')返回长度必须是32,否则报ORA-28234 - IV必须与算法匹配(如AES-CBC需16字节),且每次加密应随机生成,不能复用或硬编码
- 加密输出是
RAW,存入表或传给应用前必须用UTL_ENCODE.BASE64_ENCODE转义,否则隐式转换会损坏二进制数据
权限问题容易解决,但参数层面的细节一旦错位,错误信息(如ORA-28235、ORA-29275)看起来像权限问题,实际是类型或编码链断裂。


















