萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 加密函數實戰:ENCODE/DECODE、AES_ENCRYPT/AES_DECRYPT 保護敏感資料

Web 應用儲存密碼、身分證、信用卡等敏感資料時,MySQL 內建加密函數提供資料庫層面保護。分為**雙向加密** (可解密) 與**單向雜湊** (不可逆),按安全等級選用。

一、雙向加密:ENCODE / DECODE (舊版、弱加密)

-- 插入加密密碼
INSERT INTO users (username, password) 
VALUES ('joe', ENCODE('guessme', 'abracadabra'));
-- 儲存為二進位字串

-- 驗證時解密比對
SELECT DECODE(password, 'abracadabra') FROM users WHERE username = 'joe';
-- 回傳 'guessme'

缺點:演算法專有、強度低、MySQL 8.0 已移除。**不建議新專案使用**。

二、雙向強加密:AES_ENCRYPT / AES_DECRYPT (推薦)

-- AES-128-ECB 模式,金鑰長度 16 字元
INSERT INTO users (username, password) 
VALUES ('joe', AES_ENCRYPT('guessme', '16byteslongkey!'));

-- 解密
SELECT AES_DECRYPT(password, '16byteslongkey!') FROM users WHERE username = 'joe';
-- 回傳二進位,需 CAST: CAST(AES_DECRYPT(...) AS CHAR)

關鍵點:

  • 金鑰長度:16/24/32 字元對應 AES-128/192/256
  • 同一金鑰加解密,**金鑰管理至關重要** (建議存於環境變數/密碼保險箱,不寫死代碼)
  • 輸出為 VARBINARY,查詢時需 CAST(... AS CHAR) 或 HEX() 顯示

三、單向雜湊:MD5 / SHA1 / SHA2 (密碼儲存標準)

-- 儲存雜湊值 (不可逆)
INSERT INTO users (username, password_hash) 
VALUES ('joe', SHA2('guessme', 256));  -- SHA-256

-- 驗證:雜湊比對
SELECT COUNT(*) FROM users 
WHERE username = 'joe' AND password_hash = SHA2('input_pass', 256);

最佳實踐:加鹽

-- 註冊時
SET @salt = SUBSTRING(MD5(RAND()), 1, 8);
SET @hash = SHA2(CONCAT(@salt, 'guessme'), 256);
INSERT INTO users (username, password_hash, salt) VALUES ('joe', @hash, @salt);

-- 登入驗證
SELECT password_hash, salt FROM users WHERE username = 'joe';
-- 應用層計算 SHA2(CONCAT(salt, input_pass), 256) 比對

四、應用層整合範例 (PHP PDO)

$stmt = $pdo->prepare("SELECT password_hash, salt FROM users WHERE username = ?");
$stmt->execute([$username]);
$row = $stmt->fetch();
if ($row && hash_equals($row['password_hash'], hash('sha256', $row['salt'] . $input_pass))) {
    // 登入成功
}

選型決策表

場景推薦函數金鑰管理備註
密碼儲存SHA2(..., 256) + Salt無 (單向)業界標準,配合 bcrypt/argon2 更佳
身分證/銀行卡 (需解密顯示)AES_ENCRYPT/AES_DECRYPT環境變數/金鑰管理系統符合 PCI-DSS 加密儲存要求
一般敏感欄位 (內部系統、低風險)ENCODE/DECODE應用配置檔僅相容舊系統,新專案禁用

效能與限制

  • 加解密在 DB 層執行,減少網路傳輸明文風險
  • 大量資料加密查詢**無法使用索引** (需解密後比對),建議應用層加密後存雜湊索引
  • MySQL 8.0 移除 ENCODE/DECODE,遷移至 AES_ENCRYPT 或應用層加密
copyright © 萬盛學電腦網 all rights reserved