Oracle加密的原理就是先对源码进行lz压缩lzstr,然后对压缩数据进行SHA-1运算得到40位的加密串shstr,然后将加密串与压缩串拼接得到shstr+lzstr,然后对拼接后的字符串进行Oracle双字符转换(转换表)。最后将转换后的字符串进行base64编码,最终得到wrap的加密串。
unwarp
在线网页unwarp
https://www.codecrete.net/UnwrapIt/
set lines 400 pages 0
set long 999999
col ddl_sql for a400
select dbms_metadata.get_ddl('PACKAGE_BODY','DBMS_AUDIT_MGMT','AUDSYS') DDL_SQL from dual;


使用SQL Developer 的第三方扩展包
https://github.com/Trivadis/plsql-unwrapper-sqldev/releases



warp
https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/plsql-source-text-wrapping.html#GUID-AB6FFBAD-DE20-4197-A885-AF81F3766FA2
可以加密以下类型
- Package specification
- Package body
- Type specification
- Type body
- Function
- Procedure
使用warp命令加密
wrap iname=input_file [ oname=output_file ] [ keep_comments=yes ]
#参数keep_comments=yes 保存注释,默认会删除注释
示例
-- The following statement will not change.
SELECT COUNT(*) FROM EMPLOYEES
/
/* The PL/SQL source text of the following two CREATE statements will be wrapped. */
CREATE OR REPLACE PROCEDURE wraptest AUTHID CURRENT_USER /* C style comment in procedure declaration */ IS
TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER;
all_emps emp_tab;
BEGIN
SELECT * BULK COLLECT INTO all_emps FROM employees;
FOR i IN 1..10 LOOP /* C style in pl/sql source */
DBMS_OUTPUT.PUT_LINE('Emp Id: ' || all_emps(i).employee_id);
END LOOP;
END;
/
CREATE OR REPLACE FUNCTION fibonacci (
n PLS_INTEGER
) RETURN PLS_INTEGER
AUTHID CURRENT_USER -- PL/SQL style comment inside fibonacci function spec
IS
fib_1 PLS_INTEGER := 0;
fib_2 PLS_INTEGER := 1;
BEGIN
IF n = 1 THEN -- terminating condition
RETURN fib_1;
ELSIF n = 2 THEN
RETURN fib_2; -- terminating condition
ELSE
RETURN fibonacci(n-2) + fibonacci(n-1); -- recursive invocations
END IF;
END;
/
wrap iname=wraptest2.sql oname=wraptest2.plb keep_comments=yes PL/SQL Wrapper: Release 19.0.0.0.0 - Production on Tue Dec 17 13:42:43 2024 Version 19.13.0.0.0 Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved. Processing wraptest2.sql to wraptest2.plb
SQL> @wraptest2.plb
COUNT(*)
----------
107
Procedure created.
Function created.
-- 已经加密
SQL> r
1* SELECT text FROM USER_SOURCE WHERE name='WRAPTEST'
PROCEDURE wraptest wrapped
a000000
369
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
128 138
Mxl1sU3cJLGCCwcVnbrv2czWD7swg+nwJK5qZ3SVWE4+GayDZaL1bF7RwYm2/zr1qjZY3FrN
48M1bKc/MG5aY9YB+DrtT4SJN370Rpq7ck5D0sc1D5sKAwTyX13HYvRmjwkdXa0vEZ4q/mCU
EQusX23UZbZjxha7CtlCDCx8guGw/M/oHZXc8wDHXL8V8OsqQMv/Hj7z68gINl7OstalRScr
uSZ/l/W1YaaA9Lj8Fbx5/nJw96aN+/bow2NdacAKXDFCg0h9HnS/z685sR4knx6fzbKjkFVi
cZufAjLw3FVqLKnbLrQ=
-- 可以正常使用
SQL> set serveroutput on
SQL> BEGIN
2 wraptest; -- invoke procedure
3 DBMS_OUTPUT.PUT_LINE('fibonacci(5) = ' || fibonacci(5));
4 END;
5 /
Emp Id: 100
Emp Id: 101
Emp Id: 102
Emp Id: 103
Emp Id: 104
Emp Id: 105
Emp Id: 106
Emp Id: 107
Emp Id: 108
Emp Id: 109
fibonacci(5) = 3
PL/SQL procedure successfully completed.
sqlplus -s / as sysdba<<!
set lines 200 pages 0
set long 999999
set feed off
col ddl_sql for a200
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',true);
spool $4/$1_$2_$3\.sql
select dbms_metadata.get_ddl('$1','$2','$3') ddl_sql from dual;
exit
spool off
!
sed -i -E 's/\bEDITIONABLE\b//i' $4/$1_$2_$3\.sql
wrap iname=$4/$1_$2_$3\.sql oname=$1_$2_$3.plb keep_comments=yes
sqlplus -s / as sysdba<<!
@$4/$1_$2_$3\.plb
!
sh wrap.sh PROCEDURE WRAPTEST HR /home/oracle
使用存储过程加密
--整个ddl 32k
DBMS_DDL.CREATE_WRAPPED (
ddl VARCHAR2);
--支持单行最长256 bytes
DBMS_DDL.CREATE_WRAPPED(
ddl DBMS_SQL.VARCHAR2A,
lb PLS_INTEGER,
ub PLS_INTEGER);
--支持单行32k(采用这种)
DBMS_DDL.CREATE_WRAPPED(
ddl DBMS_SQL.VARCHAR2S,
lb PLS_INTEGER,
ub PLS_INTEGER);
DECLARE
l_source DBMS_SQL.VARCHAR2A; -- 用于存储源代码
l_wrap DBMS_SQL.VARCHAR2A; -- 用于存储加密后的代码
l_line NUMBER; -- 用于存储行号
l_text VARCHAR2(4000); -- 用于存储每一行的文本
l_object_name VARCHAR2(30) := 'WRAPTEST'; -- 对象名称
l_object_type VARCHAR2(30) := 'PROCEDURE'; -- 对象类型
BEGIN
-- 从 USER_SOURCE 中获取源代码
FOR rec IN (
SELECT LINE, TEXT
FROM USER_SOURCE
WHERE NAME = l_object_name
AND TYPE = l_object_type
ORDER BY LINE
) LOOP
l_line := rec.LINE;
l_text := rec.TEXT;
-- 如果是第一行,加上 "CREATE OR REPLACE"
IF l_line = 1 THEN
l_source(l_line) := 'CREATE OR REPLACE ' || l_text;
ELSE
l_source(l_line) := l_text;
END IF;
END LOOP;
-- 使用 DBMS_DDL.CREATE_WRAPPED 加密源代码
SYS.DBMS_DDL.CREATE_WRAPPED(
ddl => l_source,
lb => 1,
ub => l_source.count
);
END;
/
测试步骤
SQL> @wraptest2
COUNT(*)
----------
107
Procedure created.
Function created.
SQL> set lines 222
SQL> col text for a120
SQL> SELECT LINE, TEXT FROM USER_SOURCE WHERE NAME = 'WRAPTEST' ORDER BY LINE;
LINE TEXT
---------- ------------------------------------------------------------------------------------------------------------------------
1 PROCEDURE wraptest AUTHID CURRENT_USER /* C style comment in procedure declaration */ IS
2 TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER;
3 all_emps emp_tab;
4 BEGIN
5 SELECT * BULK COLLECT INTO all_emps FROM employees;
6 FOR i IN 1..10 LOOP /* C style in pl/sql source */
7 DBMS_OUTPUT.PUT_LINE('Emp Id: ' || all_emps(i).employee_id);
8 END LOOP;
9 END;
9 rows selected.
SQL> exec wraptest();
PL/SQL procedure successfully completed.
SQL> SET SERVEROUTPUT ON SIZE UNLIMITED
SQL> exec wraptest();
Emp Id: 100
Emp Id: 101
Emp Id: 102
Emp Id: 103
Emp Id: 104
Emp Id: 105
Emp Id: 106
Emp Id: 107
Emp Id: 108
Emp Id: 109
PL/SQL procedure successfully completed.
SQL>
SQL> DECLARE
2 l_source DBMS_SQL.VARCHAR2A; -- 用于存储源代码
3 l_wrap DBMS_SQL.VARCHAR2A; -- 用于存储加密后的代码
4 l_line NUMBER; -- 用于存储行号
5 l_text VARCHAR2(4000); -- 用于存储每一行的文本
6 l_object_name VARCHAR2(30) := 'WRAPTEST'; -- 对象名称
7 l_object_type VARCHAR2(30) := 'PROCEDURE'; -- 对象类型
8 BEGIN
9 -- 从 USER_SOURCE 中获取源代码
10 FOR rec IN (
11 SELECT LINE, TEXT
12 FROM USER_SOURCE
13 WHERE NAME = l_object_name
14 AND TYPE = l_object_type
15 ORDER BY LINE
16 ) LOOP
17 l_line := rec.LINE;
18 l_text := rec.TEXT;
19
20 -- 如果是第一行,加上 "CREATE OR REPLACE"
21 IF l_line = 1 THEN
22 l_source(l_line) := 'CREATE OR REPLACE ' || l_text;
23 ELSE
24 l_source(l_line) := l_text;
25 END IF;
26 END LOOP;
27
28 -- 使用 DBMS_DDL.CREATE_WRAPPED 加密源代码
29 SYS.DBMS_DDL.CREATE_WRAPPED(
30 ddl => l_source,
31 lb => 1,
32 ub => l_source.count
33 );
34 END;
35 /
PL/SQL procedure successfully completed.
SQL> set lines 222
SQL> col text for a120
SQL> SELECT LINE, TEXT FROM USER_SOURCE WHERE NAME = 'WRAPTEST' ORDER BY LINE;
LINE TEXT
---------- ------------------------------------------------------------------------------------------------------------------------
1 PROCEDURE wraptest wrapped
a000000
369
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
LINE TEXT
---------- ------------------------------------------------------------------------------------------------------------------------
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
128 138
Mxl1sU3cJLGCCwcVnbrv2czWD7swg+nwJK5qZ3SVWE4+GayDZaL1bF7RwYm2/zr1qjZY3FrN
48M1bKc/MG5aY9YB+DrtT4SJN370Rpq7ck5D0sc1D5sKAwTyX13HYvRmjwkdXa0vEZ4q/mCU
LINE TEXT
---------- ------------------------------------------------------------------------------------------------------------------------
EQusX23UZbZjxha7CtlCDCx8guGw/M/oHZXc8wDHXL8V8OsqQMv/Hj7z68gINl7OstalRScr
uSZ/l/W1YaaA9Lj8Fbx5/nJw96aN+/bow2NdacAKXDFCg0h9HnS/z685sR4knx6fzbKjkFVi
cZufAjLw3FVqLKnbLrQ=
SQL>
SQL> SET SERVEROUTPUT ON SIZE UNLIMITED
SQL> exec wraptest();
Emp Id: 100
Emp Id: 101
Emp Id: 102
Emp Id: 103
Emp Id: 104
Emp Id: 105
Emp Id: 106
Emp Id: 107
Emp Id: 108
Emp Id: 109
PL/SQL procedure successfully completed.
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




