SQL Server 2005 在可擴展金鑰管理 (EKM) 及資料庫檔案本身加密方面存在不足。SQL Server 2008 引入透明資料加密 (TDE),使用資料庫加密金鑰 (DEK) 對資料檔案(含 I/O 作業、記憶體中資料)進行即時加解密。DEK 由 master 資料庫中的憑證保護,亦支援 EKM 模組。採用標準 DES 與 AES 演算法,有效防禦伺服器被竊、資料檔案被惡意附加掛載等風險。
/* Title: TDE 加密實作
Environment: Windows Server 2008 Enterprise + SQL Server 2008 Enterprise
請在非生產環境測試 */
USE [master];
GO
-- 1. 建立 Master Key
CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'StrongP@ssw0rd!';
GO
-- 2. 建立保護 DEK 的憑證
CREATE CERTIFICATE TDE_Cert WITH SUBJECT = N'TDE Certificate for DEK Protection';
GO
-- 3. 建立測試資料庫
IF DB_ID('TDE_TestDB') IS NOT NULL DROP DATABASE TDE_TestDB;
CREATE DATABASE TDE_TestDB;
GO
USE TDE_TestDB;
GO
-- 4. 建立由憑證保護的 DEK (AES_128)
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_128
ENCRYPTION BY SERVER CERTIFICATE TDE_Cert;
GO
/* 此時會出現警告:請立即備份憑證與私鑰,否則異機還原/附加將失敗 */
-- 5. 備份憑證與私鑰 (關鍵步驟)
USE master;
BACKUP CERTIFICATE TDE_Cert
TO FILE = 'D:\Backup\Certs\TDE_Cert.cer'
WITH PRIVATE KEY (
FILE = 'D:\Backup\Certs\TDE_Cert.pvk',
ENCRYPTION BY PASSWORD = 'StrongP@ssw0rd!'
);
GO
-- 6. 備份 Master Key
BACKUP MASTER KEY
TO FILE = 'D:\Backup\Certs\MasterKey.key'
ENCRYPTION BY PASSWORD = 'StrongP@ssw0rd!';
GO
-- 7. 啟用 TDE (建議單用戶模式下執行)
ALTER DATABASE TDE_TestDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
ALTER DATABASE TDE_TestDB SET ENCRYPTION ON;
GO
ALTER DATABASE TDE_TestDB SET MULTI_USER;
GO
-- 8. 驗證加密狀態 (encryption_state = 3 表示已加密)
SELECT DB_NAME(database_id), encryption_state
FROM sys.dm_database_encryption_keys;
/* 注意:啟用 TDE 的實例中,tempdb 也會被自動加密 */
-- 9. 異機附加測試:模擬資料檔案被盜、嘗試附加
-- 來源伺服器分離
USE master;
EXEC sp_detach_db N'TDE_TestDB';
GO
-- 將 .mdf/.ldf 複製到目標伺服器
-- 目標伺服器還原 Master Key
RESTORE MASTER KEY
FROM FILE = 'D:\Backup\Certs\MasterKey.key'
DECRYPTION BY PASSWORD = 'StrongP@ssw0rd!'
ENCRYPTION BY PASSWORD = 'StrongP@ssw0rd!';
GO
-- 目標伺服器建立憑證 (從備份檔案)
CREATE CERTIFICATE TDE_Cert
FROM FILE = 'D:\Backup\Certs\TDE_Cert.cer'
WITH PRIVATE KEY (
FILE = 'D:\Backup\Certs\TDE_Cert.pvk',
DECRYPTION BY PASSWORD = 'StrongP@ssw0rd!'
);
GO
-- 目標伺服器附加資料庫 (成功即證明 TDE 保護有效)
CREATE DATABASE TDE_TestDB
ON PRIMARY (FILENAME = 'D:\Data\TDE_TestDB.mdf')
LOG ON (FILENAME = 'D:\Data\TDE_TestDB_log.ldf')
FOR ATTACH;
GO