為什麼要在資料庫層加密?
防禦深度:網路層 (IPSec/SSL)、應用層 (參數化)、資料庫層 (TDE/欄位加密)、儲存層 (EFS/BitLocker)。資料庫層加密確保**即使備份檔、資料檔被竊取,敏感欄位 (身分證、信用卡、密碼雜湊) 仍不可讀**。
方案一:內建雜湊函數 (僅適用密碼驗證,不可逆)
-- 儲存雜湊
DECLARE @pwd NVARCHAR(128) = 'P@ssw0rd';
DECLARE @hash VARBINARY(256) = HASHBYTES('SHA2_256', @pwd); -- SQL 2012+
-- 驗證
IF HASHBYTES('SHA2_256', @input) = @hash PRINT 'Match';
- ✅ 無金鑰管理、效能極佳。
- ❌ 單向、不可解密、不適用需原文場景 (信用卡、身分證)。
- ⚠️ 舊版
PWDENCRYPT/PWDCOMPARE 已棄用、演算法弱、跨版本不相容,嚴禁新專案使用。
方案二:對稱金鑰加密 (資料庫內建,雙向、效能好)
建立金鑰體系
-- 1. 主金鑰 (DMK) - 受服務主金鑰 (SMK) 保護
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Str0ngDMKPassword!';
-- 2. 憑證 - 受 DMK 保護
CREATE CERTIFICATE Cert_DataEncryption
WITH SUBJECT = 'Column Encryption Certificate',
EXPIRY_DATE = '2030-12-31';
-- 3. 對稱金鑰 - 受憑證保護
CREATE SYMMETRIC KEY SymKey_Data
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE Cert_DataEncryption;
加密/解密操作
-- 加密
OPEN SYMMETRIC KEY SymKey_Data DECRYPTION BY CERTIFICATE Cert_DataEncryption;
DECLARE @plain NVARCHAR(100) = 'A123456789'; -- 身分證
DECLARE @cipher VARBINARY(MAX) = ENCRYPTBYKEY(KEY_GUID('SymKey_Data'), @plain);
CLOSE SYMMETRIC KEY SymKey_Data;
-- 將 @cipher 存入 VARBINARY 欄位
-- 解密
OPEN SYMMETRIC KEY SymKey_Data DECRYPTION BY CERTIFICATE Cert_DataEncryption;
SELECT CONVERT(NVARCHAR(100), DECRYPTBYKEY(CipherCol)) AS PlainText FROM SensitiveTable;
CLOSE SYMMETRIC KEY SymKey_Data;
優缺點
| 優點 | 缺點 |
| 原生、無外部相依、效能高 (AES-NI 硬體加速) | 金鑰在資料庫內,DBA 可見;需妥善備份 DMK/憑證/對稱金鑰 |
| 支援 T-SQL 無縫整合、可用於索引 (加密後非確定性較難) | 輪換金鑰需重新加密全表資料 (停機或分批) |
方案三:非對稱金鑰 / 憑證加密 (公開金鑰加密、私鑰解密)
-- 加密 (公開金鑰,可在前端/應用層執行)
DECLARE @cipher VARBINARY(MAX) = ENCRYPTBYCERT(CERT_ID('Cert_DataEncryption'), @plain);
-- 解密 (私鑰,需開啟憑證私鑰存取)
SELECT CONVERT(NVARCHAR(100), DECRYPTBYCERT(CERT_ID('Cert_DataEncryption'), CipherCol, N'CertPrivateKeyPwd'));
- 適用:應用層加密、資料庫只解密;或跨系統傳遞加密資料。
- 效能較對稱金鑰慢 10~100 倍,**不適合大量資料**。
方案四:Always Encrypted (SQL 2016+ / Azure SQL) — 客戶端加密,資料庫不可見
- 金鑰儲存於 **客戶端 (Windows Certificate Store / Azure Key Vault / HSM)**,資料庫僅存密文。
- 驅動程式 (ODBC/JDBC/ADO.NET) 自動透明加解密,應用程式幾乎無感。
- 支援確定性加密 (可索引、JOIN、GROUP BY) 與隨機加密 (最高安全性)。
- 限制:不支援 Like、範圍查詢、運算式、複雜型別;需應用程式升級驅動程式。
方案五:透明資料庫加密 (TDE) — 檔案層級靜態加密
-- 1. Master Key & Certificate
USE master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Str0ng!';
CREATE CERTIFICATE TDE_Cert WITH SUBJECT = 'TDE Certificate';
-- 2. 資料庫加密金鑰 (DEK)
USE TargetDB;
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE TDE_Cert;
-- 3. 啟用 TDE
ALTER DATABASE TargetDB SET ENCRYPTION ON;
- ✅ 零應用程式變更、備份/記錄檔/Tempdb 同步加密、符合合規 (PCI DSS、GDPR)。
- ❌ 不保護記憶體中資料、不防禦 DBA/系統管理員、CPU 額外開銷 ~1-3%。
方案六:第三方擴充套件 (XP_CRYPT、ASPEncrypt、自定義 CLR)
- XP_CRYPT (ActiveCrypt): 擴充預存程序,支援 DES/3DES/AES/RSA/MD5/SHA,免費版有長度限制。
- ASPEncrypt (Persits Software): COM 元件,ASP/ASP.NET 傳統應用常用。
- CLR 整合: 將 .NET `System.Security.Cryptography` 封裝為 UDF/預存程序,彈性最高、效能佳,需啟用 `clr enabled`。
金鑰管理生命週期 (關鍵!)
- 備份:
BACKUP MASTER KEY, BACKUP CERTIFICATE ... WITH PRIVATE KEY, BACKUP SYMMETRIC KEY 至離線加密儲存。
- 輪換: 定期 (年/半年) 產生新金鑰,分批 `DECRYPTBYKEY` + `ENCRYPTBYKEY` 重新加密,舊金鑰保留解密舊備份用。
- 撤銷: 憑證過期自動失效;對稱金鑰需應用層協調停用。
- 稽核: 記錄所有 `OPEN/CLOSE KEY`、`ENCRYPTBY*`、`DECRYPTBY*` 呼叫 (Extended Events)。
選型決策矩陣
| 需求 | 推薦方案 | 備註 |
| 密碼驗證 | HASHBYTES (SHA2_256/512) + Salt | 不可逆、無金鑰管理 |
| 欄位級雙向加密、高效能、資料量大 | 對稱金鑰 (AES_256) + 憑證保護 | 原生、支援索引 (確定性) |
| 前端加密、資料庫不可見明文、合規要求極高 | Always Encrypted | 需驅動程式支援、功能限制多 |
| 整個資料庫檔案/備份靜態加密、零改代碼 | TDE (Enterprise/Developer/Azure) | 不防禦內部人員、記憶體明文 |
| 跨系統加密傳遞、非對稱需求 | 非對稱金鑰/憑證 | 效能低、僅小資料量 |
| 舊版 ASP/COM 應用快速整合 | ASPEncrypt / XP_CRYPT | 維護成本高、建議遷移原生 |