使用Wrap加密,保護Oracle程式原始碼

realkid4發表於2011-05-18

 

儲存過程、函式、包等結構,表示了軟體系統的業務邏輯和領域邏輯。將業務邏輯組織在資料層之上,特別是資料庫軟體中,是一種比較傳統和常見的做法。雖然這種方式與時下流行的設計理念有差異,但是在實際工作中卻有著很多優勢。

 

 

作為領域邏輯的代表,具體的過程實現對軟體企業來說,是一筆重要的無形資產財富,是需要額外進行保護的。但是在Oracle中,我們是可以直接的看到各種函式邏輯的實現。所以,我們需要一種手段,保護在Oracle資料字典中儲存的原始碼資訊。

 

 

Oracle中,推出了Wrap技術,既可以實現程式碼的加密,使使用者不能夠直接獲取到程式程式碼的DDL語句,同時不會影響到程式程式碼的執行。在最新的Oracle版本中,提供了兩種方式進行Wrap加密。

 

ü        Wrap命令列工具,可以在命令列中實現原始碼檔案的加密;

ü        Dbms_ddl包,其中包括的方法也可以實現在PL/SQL中進行程式碼的加密;

 

 

Wrap使用時的情況

 

首先,我們可以檢視在沒有進行Wrap處理的時候,Oracle如何進行原始碼儲存。

 

演示程式碼,本文中將使用該段SP作為演示內容。

 

//儲存過程程式碼

create or replace procedure P_WRAP_TEST_NC

( o_vc_message out varchar2) is

begin

  dbms_output.put_line('Wrap Test Procedure Working !');

end P_WRAP_TEST_NC;

 

 

當沒有進行Wrap處理的時候,我們可以透過DBMS_METADATAuser_source等資料字典工具檢視到原始碼。

 

 

--wrap過程

SQL> create or replace procedure P_WRAP_TEST_NC

  2  (

  3     o_vc_message out varchar2

  4  )

  5  is

  6  begin

  7    dbms_output.put_line('Wrap Test Procedure Working !');

  8  end P_WRAP_TEST_NC;

  9  /

Procedure created //成功建立儲存過程;

 

//使用dbms_metadata獲取生成ddl

SQL> set serveroutput on size 10000;

SQL> exec dbms_output.put_line(dbms_metadata.get_ddl(object_type => 'PROCEDURE',name => 'P_WRAP_TEST_NC'));

 

  CREATE OR REPLACE PROCEDURE "SYS"."P_WRAP_TEST_NC"

(   o_vc_message out varchar2) is

begin

  dbms_output.put_line('Wrap Test Procedure Working !');

end P_WRAP_TEST_NC;

PL/SQL procedure successfully completed

 

//透過資料字典檢視,檢視原始碼;

SQL> select line,text from user_source where name='P_WRAP_TEST_NC';

      LINE TEXT

---------- --------------------------------------------------------------------------------

         1 procedure P_WRAP_TEST_NC

         2 (

         3    o_vc_message out varchar2

         4 )

         5 is

         6 begin

         7   dbms_output.put_line('Wrap Test Procedure Working !');

         8 end P_WRAP_TEST_NC;

         9

        10

10 rows selected

 

 

 

使用Wrap命令列工具進行加密處理

 

使用Wrap命令列處理是比較傳統的原始碼加密手段。思路和過程如下:

 

1.        將編寫好並且除錯好的程式,儲存為.sql原始碼檔案,儲存在本地磁碟上;

2.        透過命令列工具wrap,將原始碼檔案處理為加密過的檔案(通常為.plb格式)。此時的檔案內容,已經是加密過的;

3.        Oracle的命令列中執行處理過的加密檔案。Oracle可以將加密資訊識別為正確的程式碼資訊,並且將加密文儲存在資料字典中;

4.        開發人員要妥善保管原始碼檔案,防止丟失;

 

下面進行過程演示。

 

首先,將儲存過程定義檔案p_wrap_test_nc儲存為.sql檔案,名稱為p_wrap_test_nc.sql,之後進行處理。

 

//命令列處理

E:\>wrap iname=p_wrap_test_nc.sql name=p_res_nc.plb

PL/SQL Wrapper: Release 10.2.0.1.0- Production on 星期三 5  18 13:10:46 2011

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

 

Processing p_wrap_test_nc.sql to p_res_nc.plb

 

 

Wrap工具有兩個引數,inameonameIname指定的進行處理的檔名稱,而oname指定的是處理後的輸出檔案。

 

 

此時如果開啟輸出檔案,可以看到加密過的密文程式碼。

 

 

create or replace procedure P_WRAP_TEST_NC wrapped

a000000

93 ce

bmPSrzSW+JbvbB0IrfiI/oW92IYwg0zwfyisfI45kJpkzm6pla+NJokfFPdh3plfljn9C1nb

w3O1Zdpo9ZxuTivH2iNAtzHVSfeEjowmNvtLZd6IVzY9f4oEfz5krpcsJuGBN6u5IwMCeYI2

MTT9hjiE/+3uwnVOQwJ1GSxTNNEpkte9Tuws/sGy+FHlNX6DnVLt+Pv3Jz4d

 

(篇幅原因,有刪節

/

 

 

接下來,透過執行這些加密檔案,來建立物件。

 

//執行生成的程式碼檔案

SQL> @e:\p_res_nc.plb

Procedure created

 

 

之後,透過執行儲存過程,來確定物件建立。

 

 

--執行成功

SQL> set serveroutput on size 10000;

SQL> var x varchar2(100);

SQL> exec P_WRAP_TEST_NC(:x);

 

Wrap Test Procedure Working !

PL/SQL procedure successfully completed

x

---------

 

說明,資料庫中已經建立了該物件,可以執行成功。接下來,我們透過檢視資料字典資訊確定是否加密。

 

//獲取原始檔

SQL> exec dbms_output.put_line(dbms_metadata.get_ddl(object_type => 'PROCEDURE',name => 'P_WRAP_TEST_NC'));

  CREATE OR REPLACE PROCEDURE "SYS"."P_WRAP_TEST_NC" wrapped

a000000

7

93 ce

bmPSrzSW+JbvbB0IrfiI/oW92IYwg0zwfyisfI45kJpkzm6pla+NJokfFPdh3plfljn9C1nb

w3O1Zdpo9ZxuTivH2iNAtzHVSfeEjowmNvtLZd6IVzY9f4oEfz5krpcsJuGBN6u5IwMCeYI2

MTT9hjiE/+3uwnVOQwJ1GSxTNNEpkte9Tuws/sGy+FHlNX6DnVLt+Pv3Jz4d

(篇幅原因,有省略……

 

PL/SQL procedure successfully completed

 

//檢查資料字典資訊

SQL> select line,text from user_source where name='P_WRAP_TEST_NC';

 

      LINE TEXT

---------- --------------------------------------------------------------------------------

         1 procedure P_WRAP_TEST_NC wrapped

          bmPSrzSW+JbvbB0IrfiI/oW92IYwg0zwfyisfI45kJpkzm6pla+NJokfFPdh3plfljn9C1nb

           w3O1Zdpo9ZxuTivH2iNAtzHVSfeEjowmNvtLZd6IVzY9f4oEfz5krpcsJuGBN6u5IwMCeYI2

           MTT9hjiE/+3uwnVOQwJ1GSxTNNEpkte9Tuws/sGy+FHlNX6DnVLt+Pv3Jz4d

    

 

 

結論:使用Wrap命令列加密的原則,就是將原始碼獨立作為檔案單獨儲存,在資料字典中僅僅儲存加密過的密文。這樣,就剔除了Oracle資料庫作為原始碼容器的作用,也就防止業務邏輯和關鍵資訊演算法的丟失。

 

 

除了使用Wrap工具外,還可以使用DBMS_DDL包進行處理。這種方式就是在PL/SQL程式碼中實現加密處理。

 

DBMS_DDL包有兩個處理方法,一個為Wrap的函式,另一個是Create_Wrap的儲存過程。

 

DBMS_DDL.Wrap函式是將一個字串(或者類似的結構體),作為引數傳入其中,返回加密過的程式碼資訊。但是,wrap函式只是將程式碼加密,並不執行。

 

呼叫演示程式碼如下:

 

//呼叫程式碼

declare

  vc_sql varchar2(2000);

  vc_wraps varchar2(2000);

begin

  vc_sql := 'create or replace procedure P_WRAP_TEST_NC '

            ||'(o_vc_message out varchar2) is begin'

            ||' dbms_output.put_line(''Wrap Test Procedure'

            ||' Working !''); end P_WRAP_TEST_NC;'; 

  vc_wraps := dbms_ddl.wrap(vc_sql);

  dbms_output.put_line(vc_wraps);

end;

/

 

執行之後,結果為:

 

//執行結果

create or replace procedure P_WRAP_TEST_NC wrapped

a000000

4mpjc088ji+D2FUnX/3WKc5v04wwg0zX7Z4VfI5AOJyeYV1Of8reEsrQUXbCIKODW43Bs

/HMFMe6QQe4yGfIJ+rZ2F5Z2gJ738KL2QqdfgFLSOf5mWrhUs2n2pN2B5DkA+pcnRlWpv

Tw1rYfqBm+ZWuyhxTGQBOjysNDzGc0JqvCkjyMyqmD/+HdT2Fkw=

(篇幅原因,有省略……

 

PL/SQL procedure successfully completed

 

 

注意,此時我們並沒有建立儲存過程。如果我們此時呼叫,會是失敗。

 

 

SQL> var x varchar2(100);

SQL> exec P_WRAP_TEST_NC(:x); //執行儲存過程;

begin P_WRAP_TEST_NC(:x); end;

ORA-06550: 1 , 7 :

PLS-00201: identifier 'P_WRAP_TEST_NC' must be declared

ORA-06550: 1 , 7 :

PL/SQL: Statement ignored

 

 

 

DBMS_DDL包的另一個方法create_wrapped,作用就是更進一步。該方法能夠直接將原始碼進行加密後建立。

 

 

--create_wrapped

SQL> declare

  2    vc_sql varchar2(2000);

  3    --vc_wraps varchar2(2000);

  4  begin

  5    vc_sql := 'create or replace procedure P_WRAP_TEST_NC '

  6              ||'(o_vc_message out varchar2) is begin'

  7              ||' dbms_output.put_line(''Wrap Test Procedure'

  8              ||' Working !''); end P_WRAP_TEST_NC;';

 10    dbms_ddl.create_wrapped(vc_sql);

 11  end;

 12  /

PL/SQL procedure successfully completed

 

 

此時,執行儲存過程,如下。

 

 

SQL> exec P_WRAP_TEST_NC(:x);

Wrap Test Procedure Working !

PL/SQL procedure successfully completed

x

---------

 

 

此時,資料字典的內容,就必然是加密過的內容。

 

 

SQL> exec dbms_output.put_line(dbms_metadata.get_ddl(object_type => 'PROCEDURE',name => 'P_WRAP_TEST_NC'));

  CREATE OR REPLACE PROCEDURE "SYS"."P_WRAP_TEST_NC" wrapped

a000000

89 c6

4mpjc088ji+D2FUnX/3Wv04wwg0zX7Z4VfI5AOJZDxyeYV1Of8reEsrQUXbCIKODW43Bs

/HMFMe6QQe4yGfIJ+rZ2FJ738KL2Qqd6zOfgFLSOf5mWrhUs2n2pN2B5DkA+pcnRlWpv

Tw1rYfqBm+ZWuyhxTGQBOjysNDzGc0JqvCkjyMyqmD/+HdT2Fkw=

 

PL/SQL procedure successfully completed

 

 

Create_wrapped方法,的確實現了加密。

 

 

使用Wrap程式碼的注意問題:

 

Wrap技術可以實現對原始碼的保護,企業核心演算法資源的保護。但是,使用的時候,最後在投產前測試再進行加密過程,而且採用額外的程式碼管理手段實現對原始檔的保護管理。

 

此外,一些物件,如觸發器等,是不能進行加密處理的。這種情況下,需要進行一些變通處理。

 

 

建議只對核心演算法進行加密處理,防止由於演算法本身問題,引起的除錯和應用問題。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-695700/,如需轉載,請註明出處,否則將追究法律責任。

相關文章