首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle PL/SQL 程式碼加密完整指南:WRAP 工具與 DBMS_DDL 套件實戰

     編輯:Oracle 資料庫相關知識

為什麼要加密 PL/SQL 程式碼?

PL/SQL 程式單元往往包含商業邏輯、演算法、加密金鑰等敏感資訊。加密(Obfuscation)可防止未經授權的人員透過 USER_SOURCE、DBA_SOURCE 直接閱讀原始碼,保護智慧財產權與安全機密。

方法一:命令列 WRAP 工具(所有版本)

基本語法

wrap iname=input.sql oname=output.plb
  • iname:輸入明文 SQL 檔案
  • oname:輸出加密後的二進位檔(副檔名慣用 .plb)

Windows 批次檔範例 (wrap.bat)

@echo off
rem 使用方式:wrap 待加密的檔案名
set NLS_LANG=AMERICAN_AMERICA.US7ASCII
wrap.exe iname=%1
pause

執行加密檔

在 SQL*Plus 中直接 @output.plb 即可建立加密物件。

方法二:DBMS_DDL 套件(10g R2 以上)

提供 PL/SQL 介面,支援動態產生與加密,適合安裝腳本、部署工具整合。

1. CREATE_WRAPPED:直接建立加密物件

BEGIN
  DBMS_DDL.CREATE_WRAPPED(
    'CREATE OR REPLACE PROCEDURE p1 AS BEGIN NULL; END;'
  );
END;
/
-- 驗證
SELECT text FROM user_source WHERE name = 'P1';
-- 輸出第一行:PROCEDURE P1 WRAPPED ...

2. WRAP 函數:取得加密文字,不立即建立物件

SELECT DBMS_DDL.WRAP('CREATE OR REPLACE PROCEDURE p1 AS BEGIN NULL; END;') FROM DUAL;
-- 輸出可存入檔案/表稍後執行

3. 處理超過 32K 的大型程式單元

使用 DBMS_SQL.VARCHAR2S (或 12c VARCHAR2A) 集合型別分段傳遞:

DECLARE
  l_input_code DBMS_SQL.VARCHAR2S;
BEGIN
  l_input_code(1) := 'CREATE OR REPLACE PROCEDURE myproc AS';
  l_input_code(2) := '  l_key VARCHAR2(200);';
  l_input_code(3) := 'BEGIN';
  l_input_code(4) := '  l_key := ''ARUPNANDA'';';
  l_input_code(5) := 'END;';
  -- LB=起始索引, UB=結束索引
  DBMS_DDL.CREATE_WRAPPED(ddl => l_input_code, lb => 1, ub => 5);
END;
/

進階應用:批量加密 Schema 下所有物件

CREATE OR REPLACE PROCEDURE p_wraped_user AUTHID CURRENT_USER AS
  v_procs DBMS_SQL.VARCHAR2A;
BEGIN
  FOR n IN (
    SELECT DISTINCT name, type
    FROM user_source
    WHERE name <> 'P_WRAPED_USER' AND type <> 'TYPE'
    MINUS
    SELECT DISTINCT name, type
    FROM user_source
    WHERE line = 1 AND INSTR(text, 'WRAPPED') > 0
    ORDER BY type
  ) LOOP
    FOR i IN (
      SELECT ROWNUM rn, text
      FROM (
        SELECT DECODE(line, 1, 'CREATE OR REPLACE ') || text AS text
        FROM user_source
        WHERE name = n.name AND type = n.type
        ORDER BY line
      )
    ) LOOP
      v_procs(i.rn) := i.text;
    END LOOP;
    DBMS_DDL.CREATE_WRAPPED(v_procs, 1, v_procs.COUNT);
    v_procs.DELETE;
  END LOOP;
END;
/

說明:

  • AUTHID CURRENT_USER 以呼叫者權限執行,存取該使用者的物件。
  • MINUS 排除已加密物件(第一行含 WRAPPED 關鍵字)。
  • 自動處理 Package Spec/Body 相依順序(按 TYPE 排序)。

重要限制與注意事項

  1. 非強加密:WRAP 為混淆非單向加密,具備逆向工程能力者仍可還原。高機密邏輯建議移至外部安全模組(如 Java Stored Procedure、External Procedure、Database Vault)。
  2. 版本相容性:加密檔通常不跨主版本相容(如 11g 加密檔無法在 12c 直接載入),升級時需重新加密。
  3. 除錯困難:加密後無法在 IDE 設定中斷點,錯誤堆疊僅顯示行號無程式碼,建議保留明文原始碼於版控系統。
  4. 動態 SQL 限制:EXECUTE IMMEDIATE 字串若包含加密物件名稱仍可呼叫,但無法動態建立加密物件(需用 DBMS_DDL)。

驗證加密狀態

SELECT name, type, 
       CASE WHEN INSTR(text, 'WRAPPED') > 0 THEN 'YES' ELSE 'NO' END AS wrapped
FROM user_source
WHERE line = 1
ORDER BY type, name;

結語

WRAP 工具與 DBMS_DDL 套件提供輕量級的 PL/SQL 程式碼保護機制。結合版控管理明文原始碼、CI/CD 流程自動加密部署,可在開發效率與資產保護間取得平衡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved