密碼、Token、PII 數據落庫前必須加密。MySQL 提供雙向 (可逆) 與單向 (不可逆) 兩大族函數,按業務場景選型。
| 函數組 | 算法 | 強度 | 適用場景 | 備註 |
|---|---|---|---|---|
ENCODE()/DECODE() | 自定義 XOR 類 | 弱 | 低敏感度配置、臨時混淆 | 5.7+ 棄用,8.0 移除 |
AES_ENCRYPT()/AES_DECRYPT() | AES-128-ECB | 中 | 配置加密、ID 遮罩、可逆業務 | Key 長度 16/24/32 字節 |
DES_ENCRYPT()/DES_DECRYPT() | DES | 極弱 | 不建議使用 | 已移除 |
-- 存儲
INSERT INTO users (uid, pwd_enc) VALUES (1, AES_ENCRYPT('my_password', 'secret_key_16bytes'));
-- 驗證 (應用層解密比對,或 SQL 直接比對)
SELECT COUNT(*) FROM users WHERE uid=1 AND AES_DECRYPT(pwd_enc, 'secret_key_16bytes') = 'my_password';
-- 查看密文 (二進制,通常用 HEX/BASE64 存儲)
SELECT HEX(AES_ENCRYPT('test', 'key1234567890123')); -- 存儲為字串
| 函數 | 算法 | 輸出長度 | 強度 | 適用場景 |
|---|---|---|---|---|
MD5() | MD5 | 32 hex | 極弱 (碰撞、彩虹表) | 非安全校驗、緩存Key |
SHA1() | SHA-1 | 40 hex | 弱 | Git 兼容、非安全 |
SHA2(str, 256) | SHA-256 | 64 hex | 強 | 應用層鹽值 + SHA256 可接受 |
SHA2(str, 512) | SHA-512 | 128 hex | 極強 | 高安全需求 |
PASSWORD() | MySQL 專用 | 41 char | 內部認證 | 不可用於業務 |
ENCRYPT() | Unix crypt() | var | 中 | 僅 *NIX、需 Salt、8.0 移除 |
// PHP 7.2+
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
// 驗證
password_verify($input, $hash);
切勿在資料庫層做密碼哈希:SQL 日誌、慢查詢、備份、複製會暴露明文/哈希。應用層加密後再寫入 DB。
SELECT 加密列權限 (通過視圖/存儲過程代理)。