wrap工具仅混淆而非加密源码,无法真正保护逻辑;明文暴露过程名、sql字符串、异常名等;权限管控(如收回select any dictionary)比wrap更有效;敏感逻辑应移至java/c或应用层。

WRAP 工具只能隐藏 USER_SOURCE,不能防专业还原
执行 wrap iname=proc.sql 后,USER_SOURCE 里确实只显示 PACKAGE BODY WRAPPED,但别误以为“源码安全”了。真实情况是:DBMS_DDL.CREATE_WRAPPED 或命令行 wrap 生成的只是混淆文本,不是加密——FyUnwrap、ora_decompile 等工具几秒就能恢复结构和逻辑流程。
更关键的是,以下内容在 wrapped 输出中仍为明文:
-
过程名、参数名、返回类型(查ALL_ARGUMENTS就能拿到) - 所有 SQL 字符串(如
'SELECT * FROM users WHERE id = :1')、异常名(NO_DATA_FOUND)、硬编码密码或密钥 - 注释若未手动删除,也会保留在输出中(部分 Oracle 版本)
权限控制比“加密”更实际有效
真正阻止开发人员看到源码,靠的不是 wrap,而是不让其有权限查字典视图。默认情况下,只要用户被授予 SELECT ANY DICTIONARY,就能直接 SELECT * FROM ALL_SOURCE 或 DBA_SOURCE,wrap 完全无效。
必须做这几件事:
- 立即收回
SELECT ANY DICTIONARY权限:这是最核心一步,否则所有防护形同虚设 - 不授
SELECT_CATALOG_ROLE给普通开发账号(该角色不含ALL_SOURCE,但含其他高危视图,非必要不给) - 确认开发账号执行
SELECT * FROM USER_SOURCE WHERE NAME = 'MY_PROC'仍可查——这是允许的;但执行SELECT * FROM ALL_SOURCE WHERE OWNER = 'OTHER_SCHEMA'应报ORA-00942 - 禁用
EXECUTEonDBMS_METADATA(因为DBMS_METADATA.GET_DDL返回的就是 wrapped 后的 DDL,且无法拦截)
DBMS_DDL.CREATE_WRAPPED 的坑比你想象的多
有人图省事想在 PL/SQL 块里动态 wrap,结果踩进一堆隐性限制:
- 传入字符串必须是完整 DDL,含结尾分号和斜杠
/,例如:'CREATE OR REPLACE PROCEDURE p AS BEGIN NULL; END; /' - 单个字符串长度上限约 32767 字节,包体稍长就会截断,报
PLS-00172: string literal too long - 不校验语法:哪怕写成
CRETE OR REPlACE...,它也照常返回 wrapped 字符串,直到你EXECUTE IMMEDIATE才报错 - 调用者必须有
EXECUTE ON DBMS_DDL,且目标 schema 可写,否则直接ORA-01031: insufficient privileges
真要保护算法逻辑,就别依赖 WRAP
如果存储过程中包含核心业务规则、加解密逻辑或风控模型,wrap 是障眼法,不是防线。此时应绕开 PL/SQL 源码暴露路径:
- 把敏感计算移到 Java Stored Procedure:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE,Oracle 不提供 Java 字节码反编译接口 - 用 C 函数封装关键逻辑:
CREATE LIBRARY+CREATE FUNCTION ... CALLING CONVENTION C,二进制库无法从数据库内提取源码 - 改由应用层处理:把逻辑下沉到微服务或中间件,数据库只做原子读写,彻底规避“源码可见”问题
最后提醒一句:wrap 文件本身是纯文本,放在版本库或开发机上等于白送——它不防拷贝,也不防泄露,唯一作用是让 SELECT * FROM USER_SOURCE 看起来“干净”一点。











