首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 加密函數保護 Web 敏感資料:雙向/單向加密實戰與最佳實務

     編輯:MySQL 綜合教學

資料加密分類與選型

類型特性MySQL 函數適用場景
雙向加密 (可逆)加密後可解密還原明文ENCODE/DECODE, AES_ENCRYPT/AES_DECRYPT需顯示明文的敏感欄位 (身分證、銀行帳號、手機)
單向加密 (不可逆)僅能驗證一致性,無法還原MD5, SHA1, SHA2, ENCRYPT, PASSWORD密碼、API Token、簽名驗證

雙向加密實戰

ENCODE/DECODE (簡易、舊版相容)

-- 插入加密資料
INSERT INTO users (username, id_card) 
VALUES ('alice', ENCODE('A123456789', 'master_key_2024'));

-- 查詢解密顯示
SELECT username, DECODE(id_card, 'master_key_2024') AS id_card 
FROM users WHERE username='alice';

-- 結果: A123456789

缺點:加密強度低、金鑰硬編碼風險、8.0 已移除。

AES_ENCRYPT/AES_DECRYPT (推薦、企業級)

-- 設定金鑰 (32 位元組 = 256 bits)
SET @key = SHA2('master_key_2024', 256);  -- 衍生固定長度金鑰

-- 插入 (HEX 格式儲存避免二進位字元集問題)
INSERT INTO users (username, id_card_enc) 
VALUES ('alice', HEX(AES_ENCRYPT('A123456789', @key)));

-- 查詢解密
SELECT username, 
       AES_DECRYPT(UNHEX(id_card_enc), @key) AS id_card
FROM users WHERE username='alice';

優點:AES-256 標準、支援金鑰輪換、相容 OpenSSL。

金鑰管理最佳實務

  • 金鑰不寫在 SQL/代碼中:使用環境變數、金鑰管理服務 (HashiCorp Vault, AWS KMS, Azure Key Vault)
  • 應用層加密:資料庫僅存密文,加解密在應用層完成 (減輕 DB CPU、金鑰不進 DB 進程)
  • 欄位級加密:僅加密敏感欄位,非敏感欄位明文 (查詢效能、索引可用)
  • 金鑰輪換機制:定期重新加密、版本化金鑰 (密文前綴標記版本)

單向加密實戰 (密碼儲存)

MD5/SHA1 (不推薦用於密碼)

-- 單純雜湊,無 Salt,極易遭 Rainbow Table 破解
INSERT INTO users (pwd_hash) VALUES (MD5('123456'));
-- 驗證
SELECT COUNT(*) FROM users WHERE pwd_hash = MD5('123456');

ENCRYPT (Unix crypt, 已棄用)

-- 內建 Salt (前 2 字元)
INSERT INTO users (pwd_hash) VALUES (ENCRYPT('123456', 'ab'));
-- 驗證需帶相同 Salt
SELECT COUNT(*) FROM users WHERE pwd_hash = ENCRYPT('123456', 'ab');

限制:僅限 *NIX 系統、長度限制、8.0 移除。

現代密碼雜湊標準:bcrypt / Argon2 / PBKDF2

MySQL 內建不支援,必須在應用層處理:

// PHP 8.1+ 範例
$hash = password_hash('123456', PASSWORD_ARGON2ID);  // 自動產生 Salt、Cost
// 驗證
if (password_verify('123456', $hash)) { /* 成功 */ }

// 儲存至 MySQL
$stmt = $pdo->prepare('INSERT INTO users (pwd_hash) VALUES (?)');
$stmt->execute([$hash]);

MySQL 欄位定義:pwd_hash VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin (支援長雜湊、區分大小寫)

應用層加密架構圖解

┌─────────────┐     加密/解密      ┌─────────────┐
│  應用服務    │ ◄────────────────► │  金鑰管理服務  │
│  (PHP/Java)  │    金鑰/加密演算法   │  (Vault/KMS)  │
└──────┬──────┘                    └─────────────┘
       │ 密文
       ▼
┌─────────────┐
│   MySQL     │  僅存密文、索引非敏感欄位
│  (儲存層)   │
└─────────────┘

資料庫層面的補充防護

措施實作方式效果
SSL/TLS 傳輸加密REQUIRE SSL 建立使用者、mysql_ssl_rsa_setup、強制 require_secure_transport=ON防中間人竊聽
靜態資料加密 (TDE)MySQL 8.0.16+ innodb_encrypt_tables=ON、金鑰環管理防磁碟/備份檔案竊取
欄位遮罩/虛擬化Views 遮罩敏感欄位、DATA_MASKING 元件 (企業版)最小權限顯示
審計日誌audit_log 插件、記錄敏感表存取事後追蹤合規

避坑指南

  1. 不要用 ENCODE/DECODE/ENCRYPT/PASSWORD:已棄用/移除、強度不足
  2. 不要在 SQL 中硬編碼金鑰:日誌、備份、程式碼庫洩露風險
  3. 不要自行設計加密演算法:使用經驗證的標準庫 (OpenSSL, libsodium)
  4. 不要將加密後資料建立索引:密文高熵值導致索引效能極差、無法範圍查詢
  5. 不要忽略金鑰備份與災難恢復演練:金鑰遺失 = 資料永久不可讀

資料加密是纵深防禦的一環,結合應用層強雜湊、資料庫層 TDE/SSL、基礎設施層金鑰管理,才能構建完整的敏感資料保護體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved