WRAP仅隐藏源码,使USER_SOURCE等视图返回不可读字节流,无法防止有权限用户执行;它不向下兼容、不可修改、不支持触发器,且注释全丢。
wrap 不能防止有权限的用户执行存储过程,只能让 all_source、user_source 等视图查不到明文源码——这是它唯一有效的防护边界。
WRAP 加密后,哪些地方再也看不到源码
加密生效后,以下途径将返回空、乱码或报错:
-
SELECT text FROM USER_SOURCE WHERE name = 'MY_PROC';→ 返回加密后的二进制字节流(不可读) -
SELECT text FROM ALL_SOURCE WHERE owner = 'SCOTT' AND name = 'PKG_TEST';→ 同样不可读,即使你有SELECT ANY DICTIONARY - SQL*Plus 中用
@wrapped_proc.sql执行没问题,但用文本编辑器打开该文件,内容已是十六进制混淆串
注意:DBA_SOURCE 也一样失效;这不是权限问题,是 Oracle 内部不解析加密块。
WRAP 工具命令行实操要点
必须用 Oracle 自带的 wrap 可执行文件,路径通常在 $ORACLE_HOME/bin/wrap。常见错误写法会导致“加密成功但无法编译”:
- 输入文件必须是纯 SQL 脚本,不能含
SET、SPOOL、DEFINE等 SQL*Plus 指令 ——wrap不解析这些 - 文件末尾必须有斜杠
/(对包体、过程、函数都强制要求),否则加密后编译报ORA-00900 - 命令格式严格:
wrap iname=proc.sql oname=proc.plb,扩展名建议用.plb(PL/SQL library)而非.sql,避免误编辑 - 加密后立即用 SQL*Plus 测试:
SQL> @proc.plb—— 成功则显示Procedure created.,失败说明原始脚本有语法错误(wrap不检查语法)
DBMS_DDL.WRAP 和 DBMS_DDL.CREATE_WRAPPED 的区别
两者都走 PL/SQL 接口,但行为关键不同:
-
DBMS_DDL.WRAP('CREATE OR REPLACE PROCEDURE p AS BEGIN NULL; END;')→ 只返回加密后的字符串,不执行、不创建对象 -
DBMS_DDL.CREATE_WRAPPED('CREATE OR REPLACE PROCEDURE p AS BEGIN NULL; END;')→ 直接编译并创建加密对象,等价于先WRAP再@xxx.plb - 若动态拼接 DDL 字符串,注意单引号要双写:
'CREATE OR REPLACE PROCEDURE x AS BEGIN DBMS_OUTPUT.PUT_LINE(''hello''); END;' - 二者都不校验表是否存在、列名是否合法 —— 错误只在运行时暴露
最容易被忽略的兼容性与维护陷阱
WRAP 加密不是“一劳永逸”,几个硬约束常被低估:
- 加密文件**不向下兼容**:19c 生成的
.plb无法在 12.2 数据库中运行,报ORA-24344或直接拒绝编译 - 加密后无法修改:想改一行逻辑?必须找回原始未加密的
.sql文件,改完再重跑wrap—— 没有“解密编辑再加密”的路径 - 注释全部丢失:所有
--和/* */在加密后消失,调试时别指望靠注释定位 - 触发器不能直接加密:
WRAP不支持CREATE TRIGGER,得把逻辑抽成过程,再让触发器调用该加密过程
真正要防的是交付环境里的源码泄露,不是防 DBA 查看 —— 如果对方能连上你的生产库且有 DBA 权限,WRAP 没意义。它只在“客户现场部署”或“第三方集成商交付”这类场景里起效。


















