首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 加密函數實戰:雙向加密、單向哈希保護 Web 敏感數據

     編輯:MySQL 資料庫相關知識

Web 應用存儲密碼、身份證、銀行卡等敏感信息時,數據庫層面加密是纵深防御關鍵一環。MySQL 內置多種加密函數,本文對比雙向加密、單向哈希特性與適用場景。

雙向加密:可逆,需密鑰管理

ENCODE() / DECODE()(已棄用,5.7+ 移除)

INSERT INTO users (username, password) VALUES ('joe', ENCODE('guessme', 'abracadabra'));
SELECT DECODE(password, 'abracadabra') FROM users WHERE username='joe';  -- 返回 'guessme'
  • 密鑰硬編碼在 SQL 中,源碼洩露即密鑰洩露
  • 加密強度弱,僅簡要混淆
  • 不推薦生產使用

AES_ENCRYPT() / AES_DECRYPT()(推薦雙向方案)

-- AES-128-ECB 模式(MySQL 默認)
INSERT INTO users (username, ssn) VALUES ('joe', AES_ENCRYPT('123-45-6789', 'master_key_16B'));
SELECT AES_DECRYPT(ssn, 'master_key_16B') FROM users WHERE username='joe';
  • 密鑰長度:16/24/32 字節對應 AES-128/192/256
  • ECB 模式無 IV,相同明文產生相同密文(可見模式攻擊)
  • MySQL 8.0.16+ 支持 AES_ENCRYPT(str, key, 'aes-256-cbc', iv) 指定 CBC 模式

單向哈希:不可逆,驗證不存明文

MD5()(不安全,僅校驗用)

INSERT INTO users (username, password_hash) VALUES ('joe', MD5('guessme'));
SELECT COUNT(*) FROM users WHERE username='joe' AND password_hash = MD5('guessme');
  • 無鹽值,彩虹表秒破
  • 碰撞攻擊風險
  • 嚴禁用於密碼存儲

SHA2() 系列(SHA-256/512,需自帶鹽值)

-- 應用層生成鹽值
$salt = random_bytes(16);
$hash = hash('sha256', $password . $salt);
-- 存儲 $hash 和 $salt

MySQL 5.5+ 支持 SHA2(str, 256|512),但鹽值管理仍需應用層處理。

ENCRYPT()(基於系統 crypt,僅 *NIX,已棄用)

INSERT INTO users (username, password_hash) VALUES ('joe', ENCRYPT('guessme', 'ab'));
SELECT COUNT(*) FROM users WHERE username='joe' AND password_hash = ENCRYPT('guessme', 'ab');
  • 自帶 2 字符鹽值,相對 MD5 稍強
  • 依賴底層 crypt(),Windows 不支持
  • 最大 8 字符密碼限制(DES 基礎)

現代最佳實踐:應用層加密 + 數據庫存密文

數據類型推薦方案關鍵點
用戶密碼bcrypt / Argon2 / PBKDF2自帶鹽、可調成本因子、應用層計算
身份證/銀行卡AES-256-GCM / ChaCha20-Poly1305認證加密、應用層管理 DEK/KEK
手機/郵箱格式保留加密 (FPE) / 令牌化保持格式便於索引/查詢
日志/審計字段級加密 + 密鑰輪換合規審計、密鑰生命週期管理

密鑰管理鐵律

  1. 密鑰不入代碼庫、不入鏡像、不入配置文件
  2. 使用 KMS / Vault / HSM 托管主密鑰 (KEK)
  3. 數據加密鑰 (DEK) 加密存儲,使用時解密入內存
  4. 定期輪換 DEK,KEK 年度輪換
  5. 備份密鑰離線存儲,多地災備

MySQL 8.0 新增:數據遮罩與去標識化

-- 動態遮罩(需權限)
SELECT masking_inner(ssn, 3, 2, 'X') FROM users;  -- 123-XX-XXXXX

-- 去標識化函數
SELECT gen_blacklist('credit_card', cc_number) FROM payments;

數據庫加密函數是戰術工具,戰略核心在應用層密碼學設計與密鑰管理體系。選對工具,管好鑰,才是真安全。

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