應用層加密雖靈活,但易出現實作不一、金鑰管理分散、備份洩漏等問題。MySQL 內建加密函數可將敏感欄位(身分證、信用卡、醫療記錄)在寫入時自動加密,讀取時解密,實現透明資料加密(TDE)雛形。
| 函數 | 演算法 | 金鑰長度 | 適用場景 |
|---|---|---|---|
AES_ENCRYPT(str, key) / AES_DECRYPT | AES-128-ECB | 16 字節(128-bit) | 通用高強度加密,推薦首選 |
DES_ENCRYPT(str, key) / DES_DECRYPT | DES/3DES | 8/24 字節 | 舊系統相容,不建議新專案 |
ENCRYPT(str, salt) | Unix crypt() | 2 字節 salt | 密碼雜湊(已棄用,改用 SHA2) |
SHA2(str, 256) / SHA2(str, 512):SHA-256/512,推薦SHA1(str):160-bit,已脆弱,禁用於安全場景MD5(str):128-bit,極易碰撞,僅用於非安全校驗PASSWORD(str):MySQL 內部認證雜湊,不可用於業務-- 生產環境金鑰應存於金鑰管理系統 (KMS)、環境變數、密碼保險箱
-- 這裡示範用固定 16 字節金鑰(實際必須輪換、分級)
SET @master_key = UNHEX('0123456789ABCDEF0123456789ABCDEF');
CREATE TABLE `users` (
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(50),
`id_card_enc` VARBINARY(100) -- 加密後二進制,長度 = 原長度填充至 16 倍數
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `users` (`name`, `id_card_enc`)
VALUES ('Alice', AES_ENCRYPT('A123456789', @master_key));
SELECT `name`, CAST(AES_DECRYPT(`id_card_enc`, @master_key) AS CHAR) AS `id_card`
FROM `users` WHERE `id` = 1;
UPDATE t SET col_enc = AES_ENCRYPT(AES_DECRYPT(col_enc, old_key), new_key)VARBINARY 儲存utf8mb4component_ssl、component_keyring:外掛式金鑰管理INNODB_TABLESPACE_ENCRYPTION:表空間級透明加密(企業版)MySQL 內建加密函數提供資料庫層面的最後一道防線。結合 AES-128 + 分級金鑰管理 + 應用層參數化,可滿足大多數合規要求。但記住:加密 ≠ 訪問控制,仍需配合權限最小化、審計日誌、網路隔離構建纵深防禦。