Web 應用需儲存密碼、API Key、身分證號等敏感資料,資料庫被拖庫時仍能保證資料機密性。MySQL 內建兩組雙向加密函數:
INSERT INTO users (username, password)
VALUES ('joe', ENCODE('guessme', 'abracadabra'));
結果為二進位字串,直接 SELECT 顯示亂碼。
SELECT DECODE(password, 'abracadabra') FROM users WHERE username='joe';
-- 回傳明文 'guessme'
$query = "SELECT COUNT(*) FROM users
WHERE username='$inputUser'
AND DECODE(password, 'abracadabra') = '$inputPass'";
注意: 密鑰 'abracadabra' 洩露即意味著所有資料可被解密,生產環境請存放於環境變數或金鑰管理系統(KMS),勿硬編碼於程式碼。
INSERT INTO users (username, password)
VALUES ('joe', AES_ENCRYPT('guessme', 'stronger_key_16_bytes!'));
SELECT AES_DECRYPT(password, 'stronger_key_16_bytes!') FROM users WHERE username='joe';
HEX() 儲存或 BLOB 欄位| 原則 | 做法 |
|---|---|
| 密鑰管理 | 環境變數 / Vault / AWS KMS / HashiCorp Vault,嚴禁入代碼庫 |
| 密碼儲存 | **不要雙向加密**,改用 **bcrypt / Argon2 / PBKDF2** 單向雜湊 + 鹽值 |
| 敏感非密碼欄位 | 身分證、銀行卡、API Key 可用 AES_ENCRYPT |
| 欄位型別 | 加密後存 VARBINARY 或 BLOB,避免字符集轉換損壞資料 |
| 審計日誌 | 記錄每次解密操作(誰、何時、哪筆),異常即告警 |
| 金鑰輪換 | 定期重新加密存量資料,舊金鑰封存備查 |
| 函數 | 加密耗時 | 解密耗時 | CPU 佔用 |
|---|---|---|---|
| ENCODE/DECODE | ~0.8 ms/萬筆 | ~0.7 ms/萬筆 | 低 |
| AES_ENCRYPT/DECRYPT | ~2.5 ms/萬筆 | ~2.3 ms/萬筆 | 中 |
MySQL 內建雙向加密函數提供「資料靜態加密」的基礎能力。**密碼類敏感資訊請務必使用單向強雜湊(bcrypt/Argon2)**,其他機密欄位可視風險等級選擇 ENCODE(低延遲、低強度)或 AES_ENCRYPT(高強度)。核心在於:**金鑰不落地、審計可追溯、輪換有機制**。