WRAP工具常“加密失败”因仅支持合法PL/SQL语法,对UTF-8无BOM、顶格CREATE开头、无SQL*Plus变量等要求严格;DBMS_DDL.CREATE_WRAPPED不校验语法且需手动拼接完整DDL;其混淆非加密,可被第三方工具格式化还原。
WRAP 命令行工具为什么经常“加密失败”或生成无效代码
wrap 不是通用加密器,它只接受符合 pl/sql 语法的源文件,且对文件编码、换行符、bom 头极度敏感。常见现象是:命令没报错,但 wrapped 后的代码在数据库里执行时报 pls-00103 或 ora-00900。
- 确保源文件是 UTF-8 无 BOM 编码(Windows 记事本默认带 BOM,会直接导致 WRAP 解析失败)
- 第一行不能是空行或注释;WRAP 要求以
CREATE OR REPLACE开头,且必须顶格写(前面不能有空格或制表符) - 不支持 SQL*Plus 变量替换(如
&table_name)、斜杠结尾(/)或匿名块(BEGIN ... END;),这些必须先手工清理 - 路径中避免中文和空格;Windows 下建议用短路径(如
C:\wrap\pkg.sql),别用 OneDrive 或桌面路径
DBMS_DDL.CREATE_WRAPPED 在 PL/SQL 块里调用的实际限制
这个函数看起来方便,但本质是把字符串动态包装成 wrapped 格式,不是运行时加密——它不校验语法,也不处理依赖,只做字面转换。一旦传入的字符串本身有语法错误,wrapped 后照样报错,而且更难调试。
- 输入字符串必须是完整、合法的 DDL 语句,包括分号(
;)和斜杠(/)都要手动拼进去,比如:'CREATE OR REPLACE PROCEDURE p AS BEGIN NULL; END; /' - 不能跨行拼接长字符串(PL/SQL 字符串字面量单行上限约 32767 字节),超长包体建议改用 WRAP 命令行处理文件
- 执行用户需有
EXECUTE权限 onDBMS_DDL,且目标 schema 必须可写(否则CREATE_WRAPPED会报ORA-01031) - 返回值是 wrapped 后的字符串,需用
EXECUTE IMMEDIATE才真正创建对象,中间没有自动编译验证
WRAP 和 CREATE_WRAPPED 生成的代码能被反解吗
不能真正“解密”,但可以被格式化还原为可读结构(非原始源码)。Oracle 的 wrap 是混淆而非加密,仅防止 casual reading;专业工具(如某些第三方 PL/SQL deparser)能恢复大部分逻辑、变量名和控制流。
- 所有常量字符串、SQL 文本、异常名、注释(如果没删)都会原样保留在 wrapped 代码中,只是被编码成 base64-like 字符串
-
SHOW PARAMETER plsql_wrap_format这类参数不存在——Oracle 不提供任何官方反解方式,但社区已有稳定解析器 - 如果你真要保护 IP,重点应放在权限控制(
GRANT EXECUTE而非SELECTon source)和代码拆分(把核心算法藏在 C library 或 Java stored procedure 里)
什么时候该用 WRAP,什么时候该放弃
WRAP 只适合内部交付、临时规避源码查看的轻量场景。只要涉及版本管理、CI/CD、多环境部署或团队协作,它就会成为维护负担。
- CI 流水线里用 WRAP 需额外维护两套脚本(源码版 + wrapped 版),且无法 diff 差异,一出问题只能重跑整个流程
- Oracle 12c+ 支持
EDITIONABLE和ACCESSIBLE BY,比 WRAP 更可控地限制访问范围 - 开发阶段一律用明文源码 + Git;上线前若强制要求“隐藏”,优先考虑用视图封装逻辑,或把敏感部分抽到外部 Web Service
WRAP 的最大陷阱是让人误以为“加了就安全了”。它既不防 DBA,也不防导出再导入,连绕过都只需要一个 SELECT text FROM all_source —— 只是 text 字段显示为乱码而已,而那串乱码,早就有公开算法能喂给解析器吐出近似源码。










