傳統權限控制只能阻擋未授權訪問,但 DBA 仍可見敏感數據(如信用卡號、身份證號)。合規與業務場景要求:即便 DBA 擁有表權限,也無法讀取特定列的明文。DB2 提供內置 SQL 加密函數,應用層透明集成,密鑰由業務持有,實現「數據擁有者可見、管理員不可見」。
| 函數 | 用途 |
|---|---|
ENCRYPT(data, password[, hint]) | 加密,返回 FOR BIT DATA 二進制串 |
DECRYPT_CHAR(encrypted, password) | 解密返回字符串 |
GETHINT(encrypted) | 提取加密時存入的密碼提示 |
SET ENCRYPTION PASSWORD = 'pwd' | 會話級設置默認密碼,避免重複傳遞 |
算法:RC2 分組密鑰 128-bit,密鑰由密碼經消息摘要派生。加密密碼與 DB2 認證體系完全無關。
適合全表統一保護,配合視圖實現透明解密:
CREATE TABLE emp (ssn VARCHAR(124) FOR BIT DATA);
SET ENCRYPTION PASSWORD = 'Ben123';
INSERT INTO emp (ssn) VALUES (ENCRYPT('289-46-8832'));
INSERT INTO emp (ssn) VALUES (ENCRYPT('222-46-1904'));
-- 視圖自動解密
CREATE VIEW clear_ssn (ssn) AS SELECT DECRYPT_CHAR(ssn) FROM emp;
-- 應用只需 SET ENCRYPTION PASSWORD 後查視圖
SET ENCRYPTION PASSWORD = 'Ben123';
SELECT ssn FROM clear_ssn;
典型場景:Web 用戶各自密碼加密自己的信用卡號。
-- 插入:用戶密碼 :userpswd 加密信用卡 :cardnum
INSERT INTO customer (ccn, name) VALUES (ENCRYPT(:cardnum, :userpswd), :custname);
-- 查詢:用戶再次輸入密碼解密
SELECT DECRYPT_CHAR(ccn, :userpswd) FROM customer WHERE name = :custname;
-- 攜帶提示
INSERT INTO customer (ccn, name) VALUES (ENCRYPT(:cardnum, :userpswd, :pswdhint), :custname);
SELECT GETHINT(ccn) INTO :pswdhint FROM customer WHERE name = :custname; -- 返回 'Ski Holiday'
通過 CAST 強制轉字符串後加密:
CREATE TABLE etemp (c1 VARCHAR(124) FOR BIT DATA);
SET ENCRYPTION PASSWORD 'next passWord';
-- TIMESTAMP
INSERT INTO etemp VALUES ENCRYPT(CHAR(CURRENT TIMESTAMP));
SELECT TIMESTAMP(DECRYPT_CHAR(c1)) FROM etemp;
-- DOUBLE
INSERT INTO etemp VALUES ENCRYPT(CHAR(1.11111002E5));
SELECT DOUBLE(DECRYPT_CHAR(c1)) FROM etemp;
VARCHAR(n) FOR BIT DATA 需預留足夠長度:加密長度 ≈ 原長度 + 8 字節開銷 + 填充對齊,建議按 原長度 * 2 + 20 估算。SET ENCRYPTION PASSWORD 適合列級;行級必須在應用層安全傳遞並管理用戶密鑰,防止密鑰洩露導致數據永久不可解密。VARCHAR FOR BIT DATA 並預留長度。hint) 降低用戶忘記密碼風險。CAST → CHAR → ENCRYPT / DECRYPT_CHAR → CAST 模式。