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

Oracle PL/SQL 實作 3DES 加解密套件:完整程式碼與應用範例

     編輯:Oracle 資料庫相關知識

資料庫層面的加密儲存是資安合規的常見需求。本文提供基於 DBMS_OBFUSCATION_TOOLKIT 實作的 3DES 加解密 PL/SQL 套件完整程式碼,含金鑰產生、資料填充/去填充、建表與測試腳本,可直接部署使用。

套件規格

  • 演算法:3DES (DES-EDE3)
  • 金鑰長度:24 位元組(3 個 8 位元組 DES 金鑰)
  • 模式:ECB / CBC(透過 iMode 參數切換)
  • 填充:PKCS#5 風格,以 # 字元補齊至 8 位元組倍數

套件規格定義

CREATE OR REPLACE PACKAGE PG_ENCRYPT_DECRYPT IS
  IKEY VARCHAR2(8) := 'Oracle9i';  -- 預設金鑰種子

  FUNCTION GEN_RAW_KEY (IKEY IN VARCHAR2) RETURN RAW;
  FUNCTION ENCRYPT_3KEY_MODE (IVALUE IN VARCHAR2, IMODE IN PLS_INTEGER) RETURN RAW;
  FUNCTION DECRYPT_3KEY_MODE (IVALUE IN RAW, IMODE IN PLS_INTEGER) RETURN VARCHAR2;
  FUNCTION FORMAT_STR  (IVALUE IN VARCHAR2) RETURN VARCHAR2;  -- 加密前填充
  FUNCTION FORMAT_STR2 (IVALUE IN VARCHAR2) RETURN VARCHAR2;  -- 解密後去填充
END;

核心實作邏輯

CREATE OR REPLACE PACKAGE BODY PG_ENCRYPT_DECRYPT IS

  FUNCTION GEN_RAW_KEY (IKEY IN VARCHAR2) RETURN RAW AS
    RAWKEY RAW(240) := '';
  BEGIN
    FOR I IN 1..LENGTH(IKEY) LOOP
      RAWKEY := RAWKEY || HEXTORAW(TO_CHAR(ASCII(SUBSTR(IKEY, I, 1))));
    END LOOP;
    RETURN RAWKEY;
  END;

  FUNCTION ENCRYPT_3KEY_MODE (IVALUE IN VARCHAR2, IMODE IN PLS_INTEGER) RETURN RAW AS
    VENCRYPTED VARCHAR2(4000);
    VENCRYPTEDRAW RAW(2048);
    RAWKEY RAW(240) := '';
  BEGIN
    RAWKEY := GEN_RAW_KEY(IKEY);
    VENCRYPTED := DBMS_OBFUSCATION_TOOLKIT.DES3ENCRYPT(
      INPUT_STRING => FORMAT_STR(IVALUE),
      KEY_STRING   => RAWKEY,
      WHICH        => IMODE
    );
    VENCRYPTEDRAW := UTL_RAW.CAST_TO_RAW(VENCRYPTED);
    RETURN VENCRYPTEDRAW;
  END;

  FUNCTION DECRYPT_3KEY_MODE (IVALUE IN RAW, IMODE IN PLS_INTEGER) RETURN VARCHAR2 AS
    VDECRYPTED VARCHAR2(4000);
    RAWKEY RAW(240) := '';
  BEGIN
    RAWKEY := GEN_RAW_KEY(IKEY);
    VDECRYPTED := DBMS_OBFUSCATION_TOOLKIT.DES3DECRYPT(
      INPUT_STRING => UTL_RAW.CAST_TO_VARCHAR2(IVALUE),
      KEY_STRING   => RAWKEY,
      WHICH        => IMODE
    );
    RETURN FORMAT_STR2(VDECRYPTED);
  END;

  -- 填充至 8 位元組倍數
  FUNCTION FORMAT_STR (IVALUE IN VARCHAR2) RETURN VARCHAR2 AS
    MVALUE VARCHAR2(4000) := IVALUE;
    I PLS_INTEGER;
  BEGIN
    I := MOD(LENGTH(MVALUE), 8);
    IF I != 0 THEN
      FOR J IN 1..(8-I) LOOP MVALUE := MVALUE || '#'; END LOOP;
    END IF;
    RETURN MVALUE;
  END;

  -- 移除填充字元
  FUNCTION FORMAT_STR2 (IVALUE IN VARCHAR2) RETURN VARCHAR2 AS
    MVALUE VARCHAR2(4000) := IVALUE;
    I PLS_INTEGER;
  BEGIN
    I := INSTR(MVALUE, '#', 1, 1);
    IF I > 0 THEN MVALUE := SUBSTR(MVALUE, 1, I-1); END IF;
    RETURN MVALUE;
  END;

END PG_ENCRYPT_DECRYPT;

應用範例:密碼加密儲存

CREATE TABLE USERS1 (
  USERID VARCHAR2(50) PRIMARY KEY,
  PASSWORD VARCHAR2(4000),   -- 明文(僅示範)
  ENCRYPTED VARCHAR2(4000)   -- 密文
);

INSERT INTO USERS1 VALUES ('user1', 'user1234yyyy', NULL);
INSERT INTO USERS1 VALUES ('user2', 'abcd1234yy', NULL);
INSERT INTO USERS1 VALUES ('user3', 'oracle12yyy', NULL);

-- 批次加密
UPDATE USERS1 SET ENCRYPTED = PG_ENCRYPT_DECRYPT.ENCRYPT_3KEY_MODE(PASSWORD, 1);

-- 查詢驗證
SELECT USERID, PASSWORD, 
       PG_ENCRYPT_DECRYPT.DECRYPT_3KEY_MODE(ENCRYPTED, 1) AS DECRYPTED
FROM USERS1;

安全性與遷移建議

  • 金鑰管理:生產環境勿硬編碼金鑰,應儲於金鑰管理系統或加密錢包,運行時動態注入
  • 演算法升級:3DES 已被視為弱演算法,新系統建議改用 DBMS_CRYPTO 的 AES-256-GCM
  • 鹽值與 IV:CBC 模式需為每筆資料產生隨機 IV,並與密文共同儲存
  • 審計追蹤:記錄加解密操作日誌,滿足合規稽核需求

此套件示範了資料庫原生加解密的完整流程,實務部署時請依組織資安政策強化金鑰生命週期管理。

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