Oracle 存储过程加密方法

我们在Oracle存储过程中所包含的商业秘密,有时不愿意被第三方人员看到,可以通过对存储过程加密来实现。

有两种加密存储过程的方法:使用wrap工具或dbms_ddl包。下面我们分解介绍一下。

 

1. wrap工具

Wrap是Oracle所提供的操作系统级的命令,语法如下:

wrap iname=input_file [oname=output_file]

参数iname为要加密的文件名,oname为加密后的文件名。如果省略oname,那么将会自动产生一个同名的加密文件名,且后缀为plb。

我们来演示一下wrap工具的用法。首先创建一个名称为test1.sql的文件:

CREATE OR REPLACE FUNCTION get_date_string RETURN VARCHAR2 AS

BEGIN

RETURN TO_CHAR(SYSDATE, ‘DD-MON-YYYY’);

END get_date_string;

/

它保存在D盘根目录。现在我来将它加密:

D:\>dir test* 驱动器 D 中的卷是 D 卷的序列号是 15C2-D261

 

   D:\ 的目录

2009-12-26 16:35               138 test1.sql

                1 个文件            138 字节

               0 个目录 2,052,046,848 可用字节

D:\>wrap iname=d:\test1.sql

PL/SQL Wrapper: Release 10.2.0.1.0- Production on 星期六 12月 26 16:36:01 2009

Copyright (c) 1993, 2004, Oracle. All rights reserved.

Processing d:\test1.sql to test1.plb

 

D:\>dir test*

驱动器 D 中的卷是 D

卷的序列号是 15C2-D261

   D:\ 的目录

2009-12-26 16:36               350 test1.plb

2009-12-26 16:35               138 test1.sql

               2 个文件            488 字节

               0 个目录 2,052,046,848 可用字节

看看加密后的文件test1.plb中的内容:

CREATE OR REPLACE FUNCTION get_date_string wrapped

a000000

354

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

8

71 ae

P29RDhRZX0orO0ED/mMF8i12Glkwg8eZgcfLCNL+XlquYvSuoVah8JbRPpdHDOrnwLK9spte

58d0wDO4dGUJuHSLwMAy/tKGCamhAs7G1hohrO/WTHaEcTKOd0xx9RBzc/XvN2dM6+zZPXLp

r1UqFBwU/Sx2010pwUjXpqZCvywG

 

/

现在你可以把文件test1.plb发给客户使用了,而不必担心你的源代码的暴露。

这个工具使用起来很简单,也很方便,尤其可以批量生成存储过程的加密文件。

2. dbms_ddl包

从Oracle 10g Release 2开始,你可以使用DBMS_DDL包来动态加密存储过程。

如果你只想将写完的源代码进行加密,就像刚才我们讲到的wrap工具那样,你可以使用dbms_ddl.wrap函数;如果你想加密源代码并在数据库中创建它,那么你可以使用dbms_ddl.create_wrapped。

2.1 wrap

如果你不想创建这个过程,而只是想获得这个加密后的创建脚本,然后把脚本发给客户去执行,这可以使用函数dbms_ddl.wrap。它的功能和“wrap“工具相同。我们先看一下这个函数的定义:

FUNCTION wrap(ddl VARCHAR2) RETURN VARCHAR2;FUNCTION wrap(ddl dbms_sql.varchar2s, lb PLS_INTEGER, ub PLS_INTEGER) RETURN dbms_sql.varchar2s;

 

FUNCTION wrap(ddl dbms_sql.varchar2a, lb PLS_INTEGER, ub PLS_INTEGER)

RETURN dbms_sql.varchar2a;

 

它被重载了三次:第一个函数接收VARCHAR2类型的输入,后两个函数接收VARCHAR2集合的输入(允许大的DDL语句的输入)。

入参ddl要求语法为”create or replace…”的字符串,用以创建包、包体、类型、类型体、函数和过程的程序单元的DDL语句。如果入参ddl所定义的程序单元不能被加密,或存在语法错误,则将抛出“MALFORMED_WRAP_INPUT”异常。

入参lb为加密集合的最低元素,ub为加密集合的最高元素。

返回值即为加密后的代码。你可以将它写入一个文件中,或者存储在表中。

我们先使用第一个wrap函数实现一个简单的应用。我想获取如下过程加密后的代码:

 

create or replace procedure p2asbegin

 

dbms_output.put_line(’yuechaotian’);

end;

 

使用wrap函数来实现它:

SQL> select dbms_ddl.wrap(’create or replace procedure p2 as begin dbms_output.put_line(”yuechaotian”); end; ‘) 2    from dual;

 

DBMS_DDL.WRAP(’CREATEORREPLACEPROCEDUREP2ASBEGINDBMS_OUTPUT.PUT_LINE(”YUECHAOTIAN”);END;’)

—————————————————————————

 

create or replace procedure p2 wrapped

a000000

354

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

7

41 7d

ND2TI3IsThvViemtwIoHec7RMCMwg5nnm7+fMr2ywFwWfAm4dCu4wDL+0l64UpuySv4osr3n

srMdBjAsriTqsoGXJXddX9vk8UfbejIu9kTqJB/2RDmmF3HTZA==

 

所生成的密文,你可以直接拷贝过来在数据库中执行:

 

SQL> create or replace procedure p2 wrapped 2 a000000 3 354

 

4 abcd

5 abcd

6 abcd

7 abcd

8 abcd

9 abcd

10 abcd

11 abcd

12 abcd

13 abcd

14 abcd

15 abcd

16 abcd

17 abcd

18 abcd

19 7

20 41 7d

21 ND2TI3IsThvViemtwIoHec7RMCMwg5nnm7+fMr2ywFwWfAm4dCu4wDL+0l64UpuySv4osr3n

22 srMdBjAsriTqsoGXJXddX9vk8UfbejIu9kTqJB/2RDmmF3HTZA==

23 /

 

过程已创建。

 

SQL> exec p2

yuechaotian

 

PL/SQL 过程已成功完成。

 

你也可以把它保存到纯文本文件或表中,在以后执行。如果你生成的代码要在其它地方部署,并且必须要保证代码的安全性,则这种方法很有用。

注意,这里的源代码是以VARCHAR2类型传递给wrap函数的。因为VARCHAR2类型的长度有限制(32767字节),对于很长的过程(比如一个2w行的包体),就得使用另外两个重载的wrap函数了:

FUNCTION wrap(ddl dbms_sql.varchar2s, lb PLS_INTEGER, ub PLS_INTEGER) RETURN dbms_sql.varchar2s;FUNCTION wrap(ddl dbms_sql.varchar2a, lb PLS_INTEGER, ub PLS_INTEGER)

 

RETURN dbms_sql.varchar2a;

这里的输入输出使用联合数组(associative array)来实现。两者的不同在于类型dbms_sql.varchar2s限制为每行256字节,而类型dbms_sql.varchar2a为32767字节。我们举一个例子:

SET SERVEROUTPUT ON SIZE UNLIMITEDDECLARE l_source DBMS_SQL.VARCHAR2A;

 

l_wrap    DBMS_SQL.VARCHAR2A;

BEGIN

l_source(1) := ‘CREATE OR REPLACE FUNCTION get_date_string RETURN VARCHAR2 AS ‘;

l_source(2) := ‘BEGIN ‘;

l_source(3) := ‘RETURN TO_CHAR(SYSDATE, ”DD-MON-YYYY”); ‘;

l_source(4) := ‘END get_date_string;’;

 

l_wrap := SYS.DBMS_DDL.WRAP(ddl => l_source,

                              lb => 1,

                              ub => l_source.count);

 

FOR i IN 1 .. l_wrap.count LOOP

    DBMS_OUTPUT.put_line(l_wrap(i));

END LOOP;

END;

/

CREATE OR REPLACE FUNCTION get_date_string wrapped

 

a000000

b2

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

8

6f

aa

mV4eMSJ8EqqgErJT91l6UZ0pdDUwgyr6LZ5GfHSmUPiJfkEObQpeDb6D7glajI+ONulxdqC1

0HvOPP4eJpQs5zxsKXpj6XL1

fvieXyWCr3BTzXTqcGYhfXrtqDVPztR/o+9UZ8l5OijDSsRW

ZPv6rISzFyqeEsCBweFUFyxd

 

 

PL/SQL procedure successfully completed.

2.2 create_wrapped

除了wrap函数外,在dbms_ddl包中还包括三个重载的create_wrapped过程:

PROCEDURE create_wrapped(ddl VARCHAR2);

PROCEDURE create_wrapped(ddl dbms_sql.varchar2s, lb PLS_INTEGER,

                         ub PLS_INTEGER);

PROCEDURE create_wrapped(ddl dbms_sql.varchar2a, lb PLS_INTEGER,

                         ub PLS_INTEGER);

它们拥有和wrap一样的入参和出参。使用方法也和wrap函数类似,不过要注意它们是过程(而不是函数)。

与函数wrap不同,过程create_wrapped不但加密源代码,而且还会在数据库中执行加密后的密文。我们先看一个例子,我要在数据库中以加密的方式创建这个过程:

create or replace procedure p1asbegin

 

dbms_output.put_line(’yuechaotian’);

end;

我可以借助过程dbms_ddl.create_wrapped:

SQL> begin 2 dbms_ddl.create_wrapped 3 (’create or replace procedure p1

 

4    as

5    begin

6      dbms_output.put_line(”yuechaotian”);

7    end;’);

8 end;

9 /

 

PL/SQL 过程已成功完成。

 

SQL> set serveroutput on

SQL> exec p1

yuechaotian

 

PL/SQL 过程已成功完成。

看看加密后的代码:

 

– 1. 从视图 user_source 中查询SQL> set pagesize 1000SQL> col text format a100

 

SQL> set line 2000

SQL> SELECT TEXT FROM user_source WHERE NAME = ‘P1′;

 

TEXT

————————————————————————–

procedure p1 wrapped

a000000

354

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

7

4a 81

aVtlrmIdKjyE1rQszxgCZ9Z7+YEwg5nnm7+fMr2ywFwWfF0Jabh0OdPc4rlBP2ejNa+V+nhX

GSQhFMohoijjhhB6c3Eqd9UMXreC004MZbZOdyo7N55Mc3HyiKbboLaf

 

– 2. 使用 get_ddl 查询

SQL> set long 10000

SQL> select dbms_metadata.get_ddl(’PROCEDURE’,'P1′) from dual;

 

DBMS_METADATA.GET_DDL(’PROCEDURE’,'P1′)

————————————————————————

 

CREATE OR REPLACE PROCEDURE “TEST”.”P1″ wrapped

a000000

354

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

7

4a 81

aVtlrmIdKjyE1rQszxgCZ9Z7+YEwg5nnm7+fMr2ywFwWfF0Jabh0OdPc4rlBP2ejNa+V+nhX

GSQhFMohoijjhhB6c3Eqd9UMXreC004MZbZOdyo7N55Mc3HYiKbboLaf

这样,你就在数据库中创建了一个加密源代码的存储过程。

为了您的安全,请只打开来源可靠的网址

打开网站    取消

来自: http://hi.baidu.com/hanbingxiaoshi/blog/item/fce5d2c4be5635a48326ac79.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值