適用場景:需原文還原的敏感欄位(如 API 金鑰、第三方憑證、可逆加密需求)。
INSERT INTO users (username, api_key) VALUES ('alice', ENCODE('sk_live_xxx', 'master_key_2024'));
SELECT DECODE(api_key, 'master_key_2024') FROM users WHERE username='alice';
⚠️ 缺點:演算法為簡易 XOR 型,密鑰長度限制,不建議用於高敏感資料。MySQL 8.0 已棄用。
-- AES-128-ECB 模式 (預設)
INSERT INTO users (username, api_key) VALUES ('alice', AES_ENCRYPT('sk_live_xxx', UNHEX(SHA2('master_key_2024', 512))));
SELECT AES_DECRYPT(api_key, UNHEX(SHA2('master_key_2024', 512))) FROM users WHERE username='alice';
SHA2('原始金鑰', 512) 產生 64 位元組金鑰,取前 16/24/32 位元組對應 AES-128/192/256。block_encryption_mode 系統變數可切換 ECB/CBC/CFB/OFB,CBC 需 IV (初始向量)。VARBINARY 或 BLOB,避免字元集轉換破壞二進位資料。適用場景:使用者密碼、API Token 雜湊、完整性校驗。不可逆,驗證時重新計算比對。
INSERT INTO users (username, pass_hash) VALUES ('bob', MD5('password123'));
SELECT COUNT(*) FROM users WHERE username='bob' AND pass_hash=MD5('password123');
⚠️ 彩虹表、GPU 破解極快,**嚴禁用於密碼儲存**。
SHA2('password123', 256) -- 64 字元十六進位字串
無鹽值,相同密碼產生相同雜湊,易受彩虹表攻擊。
-- 自動產生隨機鹽值 (前兩字元)
INSERT INTO users (username, pass_hash) VALUES ('bob', ENCRYPT('password123'));
-- 驗證需傳入完整雜湊作為鹽值
SELECT COUNT(*) FROM users WHERE username='bob' AND pass_hash=ENCRYPT('password123', pass_hash);
支援 DES、MD5、SHA-256/512、Blowfish 等演算法,視作業系統 crypt(3) 支援度而定。
MySQL 內建函數**不適合**作為現代密碼雜湊方案。請在應用層 (PHP password_hash()、Java BCrypt、Python passlib、Go golang.org/x/crypto/bcrypt) 完成雜湊,資料庫僅儲存結果字串 (CHAR(60) for bcrypt)。
| 資料類型 | 加密層級 | 推薦方案 | 金鑰管理 |
|---|---|---|---|
| 使用者密碼 | 單向強雜湊 | 應用層 bcrypt (cost≥12) / Argon2id | 無需金鑰,僅驗證 |
| API 金鑰、OAuth Token | 雙向加密 | AES-256-GCM (應用層) 或 MySQL AES_ENCRYPT (CBC+IV) | 金鑰存放於 Vault/KMS/環境變數,輪換機制 |
| PII (身分證、手機、銀行卡) | 欄位級加密 + 索引支援 | 應用層決定性加密 (AES-SIV) 或 MySQL AES_ENCRYPT + 功能性索引 (8.0+) | 分級金鑰,定期輪換 |
| 完整資料庫檔案 | 透明加密 (TDE) | InnoDB Tablespace Encryption / 磁碟加密 (LUKS/BitLocker) | 金鑰由 KMS 管理,自動輪換 |