資料庫層面的加密儲存是資安合規的常見需求。本文提供基於 DBMS_OBFUSCATION_TOOLKIT 實作的 3DES 加解密 PL/SQL 套件完整程式碼,含金鑰產生、資料填充/去填充、建表與測試腳本,可直接部署使用。
iMode 參數切換)# 字元補齊至 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;
DBMS_CRYPTO 的 AES-256-GCM此套件示範了資料庫原生加解密的完整流程,實務部署時請依組織資安政策強化金鑰生命週期管理。