SQLServer的TDE加密


TDE的主要作用是防止數據庫備份或數據文件被偷了以后,偷數據庫備份或文件的人在沒有數據加密密鑰的情況下是無法恢復或附加數據庫的。

 

首先創建SQL Server中master系統數據庫的MASTER KEY和CERTIFICATE:

USE [master];
GO


--查看master數據庫是否被加密
SELECT name,is_master_key_encrypted_by_server FROM
sys.databases;


--創建master數據庫下的主數據庫密鑰
CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'1qaz@WSX3edc$RFV';

--如果創建后要刪除master數據庫下的主數據庫密鑰,可以使用下面的語句
--DROP MASTER KEY 


--查看master數據庫下的密鑰信息
SELECT * FROM sys.symmetric_keys;


--創建證書用來保護 數據庫加密密鑰 (DEK)
CREATE CERTIFICATE master_server_certficate WITH
SUBJECT = N'Master Protect DEK Certificate';

--如果創建后要刪除master數據庫下的證書,可以使用下面的語句
--DROP CERTIFICATE master_server_certficate

 

創建測試數據庫TestDbEncryption,該數據庫將會開啟TDE加密:

CREATE DATABASE TestDbEncryption;

GO

接下來啟用數據庫TestDbEncryption的DEK 數據庫加密密鑰 (對稱密鑰)

USE TestDbEncryption;
GO

--創建由master_server_cert保護的DEK 數據庫加密密鑰 (對稱密鑰)
CREATE DATABASE ENCRYPTION KEY 
WITH ALGORITHM = AES_128
ENCRYPTION BY SERVER CERTIFICATE master_server_certficate;

--如果創建后,要刪除TestDbEncryption數據庫上的DEK 數據庫加密密鑰,可以使用下面的語句
--DROP DATABASE ENCRYPTION KEY 

--執行上面的CREATE DATABASE ENCRYPTION KEY語句以后出現:
/*
Warning: The certificate used for encrypting the database encryption key has not been backed up. You should immediately back up the certificate and the private key associated with the certificate. If the certificate ever becomes unavailable or if you must restore or attach the database on another server, you must have backups of both the certificate and the private key or you will not be able to open the database.
*/
--提示你,立刻備份證書;這里備份證書,不比制定加密私鑰的 對稱密鑰了.因為他的密鑰是通過master數據庫的主數據庫密鑰加密了.

執行上面CREATE DATABASE ENCRYPTION KEY會提示備份master系統數據庫的CERTIFICATE,所以接下來我們備份master系統數據庫的MASTER KEY和CERTIFICATE:

USE master;
GO

--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';

--備份master系統數據庫的CERTIFICATE
BACKUP CERTIFICATE master_server_certficate TO FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.cer' 
WITH PRIVATE KEY ( 
FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.pvk' , 
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV');

--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY
GO 


USE master;
GO

--相應的,我們也備份一下數據庫主密鑰(master)
--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';
BACKUP MASTER KEY TO FILE = 'D:\MSSQL_TDE_Keys\master.cer' 
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';

--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY
GO 

之后在SQL Server服務器的D:\MSSQL_TDE_Keys路徑下會出現三個文件,保存好這三個文件,如下所示:

 

下面我們就要開啟測試數據庫TestDbEncryption的TDE加密了:

USE TestDbEncryption
GO

--生產環境下,設置成單用戶在運行加密
ALTER DATABASE TestDbEncryption SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO

--開啟TDE 加密
ALTER DATABASE TestDbEncryption SET ENCRYPTION ON;
GO

--設置多用戶訪問
ALTER DATABASE TestDbEncryption SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO

--再次開啟TDE 加密,解釋下為什么在上面設置多用戶訪問后,這里還要執行一次SET ENCRYPTION ON,因為不知道是不是SQL Server的一個BUG,如果只執行上面一次SET ENCRYPTION ON,后面查詢SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys時,encryption_state的值永遠為2
ALTER DATABASE TestDbEncryption SET ENCRYPTION ON;
GO

如果開啟數據庫TestDbEncryption的TDE加密后,之后想要關閉TDE加密,可以使用下面的語句:

USE TestDbEncryption
GO

--生產環境下,設置成單用戶在運行加密
ALTER DATABASE TestDbEncryption SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO

--關閉TDE 加密
ALTER DATABASE TestDbEncryption SET ENCRYPTION OFF;
GO

--設置多用戶訪問
ALTER DATABASE TestDbEncryption SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO

--再次關閉TDE 加密,解釋下為什么在上面設置多用戶訪問后,這里還要執行一次SET ENCRYPTION OFF,因為不知道是不是SQL Server的一個BUG,如果只執行上面一次SET ENCRYPTION OFF,后面查詢SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys時,encryption_state的值永遠為5
ALTER DATABASE TestDbEncryption SET ENCRYPTION OFF;
GO

 

查看TestDbEncryption數據庫是否被加密:

--查看TestDbEncryption數據庫是否被加密 encryption_state:3 TDE加密了
SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys;
/*
發現tempdb也被加密了。MSDN解釋是:如果實例中有一個數據庫啟用了TDE加密,那么tempdb也被加密
*/

查詢結果為:

這里給出MSDN上列出的encryption_state所有值的含義:

encryption_state
Indicates whether the database is encrypted or not encrypted.

  • 0 = No database encryption key present, no encryption
  • 1 = Unencrypted
  • 2 = Encryption in progress
  • 3 = Encrypted
  • 4 = Key change in progress
  • 5 = Decryption in progress
  • 6 = Protection change in progress (The certificate or asymmetric key that is encrypting the database encryption key is being changed.)

詳情可以查看 sys.dm_database_encryption_keys (Transact-SQL)

 

 

之后我們先備份已啟用TDE的測試數據庫TestDbEncryption到數據庫備份文件TestDbEncryption.bak:

USE master;
GO

--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV';

BACKUP DATABASE TestDbEncryption
TO DISK='D:\MSSQL_Backup\TestDbEncryption.bak'

--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY

 

接下來,找另外一台機器或者實例來測試,如果數據庫備份文件被盜走了,防止被還原。這時就要用到我們前面生成的三個文件了:

先在另外一台機器還原MASTER KEY:

USE master;
GO

--先在另外一台機器還原了MASTER KEY (該機器master數據庫無master key)
RESTORE MASTER KEY 
FROM FILE = 'D:\MSSQL_TDE_Keys\master.cer' 
DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV'
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';
GO

再還原CERTIFICATE:

USE master;
GO

--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV';
--創建證書
CREATE CERTIFICATE master_server_certficate
FROM FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.cer' 
WITH PRIVATE KEY (FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.pvk', 
DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV');
GO 

--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY

 

最后使用前面准備的數據庫備份文件TestDbEncryption.bak,還原數據庫TestDbEncryption:

USE master;
GO

--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV';

RESTORE DATABASE TestDbEncryption FROM DISK='D:\MSSQL_Backup\TestDbEncryption.bak'
WITH MOVE 'TestDbEncryption'
TO 'D:\MSSQL_Data\TestDbEncryption.mdf',
MOVE 'TestDbEncryption_log'
TO 'D:\MSSQL_Log\TestDbEncryption_log.ldf'
GO


--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY

 

如果要直接附加啟用TDE的數據庫mdf和ldf文件到SQL Server,可以采用下面的語句:

USE master;
GO

--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV';

--附加數據庫
CREATE DATABASE TestDbEncryption 
ON PRIMARY 
(
FILENAME=N'C:\Users\Administrator\Desktop\TestDbEncryption.mdf'
)
LOG ON 
(
FILENAME=N'C:\Users\Administrator\Desktop\TestDbEncryption_log.ldf'
)
FOR ATTACH ;
GO

--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY

 

在還原或附加數據庫TestDbEncryption后,最好用下面的語句檢查下數據庫文件是否有錯誤:

USE master;
GO

--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV';

DBCC CHECKDB([TestDbEncryption]) WITH NO_INFOMSGS

--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY

如果DBCC CHECKDB語句沒有報錯,就沒有問題。

 

所以如果有人盜走數據庫備份文件TestDbEncryption.bak,直接拿到另外一台SQL Server服務器上還原,或者直接附加TestDbEncryption.mdf和TestDbEncryption_log.ldf數據庫文件到另一台SQL Server,是不行的,會報錯。

此外上面很多SQL腳本中使用了OPEN MASTER KEY 和 CLOSE MASTER KEY來打開和關閉MASTER KEY連接,只有像備份還原等這種關鍵SQL才需要打開和關閉MASTER KEY連接,普通的SELECT、UPDATE、INSERT、DELETE等數據操作SQL語句是不需要打開和關閉MASTER KEY連接的,TDE加密對於數據庫用戶來說是透明的,不會影響普通SQL語句的使用。

 

 

在新的SQL Server服務器或實例還原MASTER KEY和CERTIFICATE后,還需要注意的幾個地方:
首先,當你在新的SQL Server服務器或實例還原MASTER KEY和CERTIFICATE后,執行下面的SQL語句:

USE master;
GO

--查看master數據庫是否被加密
SELECT name,is_master_key_encrypted_by_server FROM
sys.databases;

你會發現master系統數據庫的is_master_key_encrypted_by_server為0

這是因為is_master_key_encrypted_by_server表示的是當前SQL Server實例使用的MASTER KEY,是否是在當前SQL Server實例中創建的,很明顯由於我們此時的MASTER KEY是通過RESTORE MASTER KEY語句還原得到的,所以不是由當前SQL Server實例創建的,因此master系統數據庫的is_master_key_encrypted_by_server為0.

MSDN上對is_master_key_encrypted_by_server的解釋如下:

The is_master_key_encrypted_by_server column of the sys.databases catalog view in master indicates whether the database master key is encrypted by the service master key.

 

詳情可以查看 CREATE MASTER KEY (Transact-SQL)

 

 

當前SQL Server實例master系統數據庫的is_master_key_encrypted_by_server為0,會引出下一個問題,那就是當前SQL Server實例中新的數據庫都無法成功開啟TDE,例如我們現在創建一個數據庫Demo

CREATE DATABASE Demo

你會發現按照我們前面介紹的方法開啟數據庫Demo的TDE后,執行如下查詢

--查看TestDbEncryption數據庫是否被加密 encryption_state:3 TDE加密了
SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys;

結果Demo的encryption_state始終為2:

這就是因為master系統數據庫的is_master_key_encrypted_by_server為0導致的。

 

所以當在新的SQL Server服務器或實例上還原或附加TestDbEncryption數據庫后,我們應該重建新的SQL Server服務器或實例的MASTER KEY和CERTIFICATE

因此當還原或附加TestDbEncryption數據庫后,我們首先應該關閉TestDbEncryption數據庫的TDE加密,如下SQL語句所示:

USE TestDbEncryption
GO

--生產環境下,設置成單用戶在運行加密
ALTER DATABASE TestDbEncryption SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO

--關閉TDE 加密
ALTER DATABASE TestDbEncryption SET ENCRYPTION OFF;
GO

--設置多用戶訪問
ALTER DATABASE TestDbEncryption SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO

--再次關閉TDE 加密,解釋下為什么在上面設置多用戶訪問后,這里還要執行一次SET ENCRYPTION OFF,因為不知道是不是SQL Server的一個BUG,如果只執行上面一次SET ENCRYPTION OFF,后面查詢SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys時,encryption_state的值永遠為5
ALTER DATABASE TestDbEncryption SET ENCRYPTION OFF;
GO

 

接着刪除數據庫TestDbEncryption的DEK 數據庫加密密鑰 (對稱密鑰)

USE TestDbEncryption;
GO

--如果創建后,要刪除TestDbEncryption數據庫上的DEK 數據庫加密密鑰,可以使用下面的語句
DROP DATABASE ENCRYPTION KEY 

 

然后刪除當前SQL Server中master系統數據庫的MASTER KEY和CERTIFICATE

USE [master]
GO

--如果創建后要刪除master數據庫下的證書,可以使用下面的語句
DROP CERTIFICATE master_server_certficate
GO

--如果創建后要刪除master數據庫下的主數據庫密鑰,可以使用下面的語句
DROP MASTER KEY 
GO

 

重新創建SQL Server中master系統數據庫的MASTER KEY和CERTIFICATE

USE [master]
GO

--創建master數據庫下的主數據庫密鑰
CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'1qaz@WSX3edc$RFV';
GO

--創建證書用來保護 數據庫加密密鑰 (DEK)
CREATE CERTIFICATE master_server_certficate WITH
SUBJECT = N'Master Protect DEK Certificate';
GO

這時再查詢

USE [master];
GO

--查看master數據庫是否被加密
SELECT name,is_master_key_encrypted_by_server FROM
sys.databases;

我們就會發現master系統數據庫的is_master_key_encrypted_by_server為1了

 

原因就是我們現在通過新的SQL Server服務器或實例,重新創建了master系統數據庫的MASTER KEY和CERTIFICATE

接着和前面一樣記住備份新創建的MASTER KEY和CERTIFICATE

USE master;
GO

--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';

--備份master系統數據庫的CERTIFICATE
BACKUP CERTIFICATE master_server_certficate TO FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.cer' 
WITH PRIVATE KEY ( 
FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.pvk' , 
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV');

--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY
GO 


USE master;
GO

--相應的,我們也備份一下數據庫主密鑰(master)
--打開數據庫連接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';
BACKUP MASTER KEY TO FILE = 'D:\MSSQL_TDE_Keys\master.cer' 
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';

--關閉數據庫連接MASTER KEY
CLOSE MASTER KEY
GO

 

最后按照本文前面說的方法,開啟新的SQL Server服務器或實例上各個數據庫的TDE加密就行了,這時新的SQL Server服務器或實例上的數據庫應該都可以成功開啟TDE加密了,開啟后查詢

--查看TestDbEncryption數據庫是否被加密 encryption_state:3 TDE加密了
SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys;

encryption_state都應該為3了

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM