什么是透明數據加密?
TDE的執行。
我的數據庫現在是安全的嗎?
在激活TDE之前需要考慮什么?
當激活TDE之后會影響什么?
什么是透明數據加密?
Microsoft SQL Server 2008推出了另一個級別的加密——透明數據加密。TDE是全數據庫級別的加密,它不局限于字段和記錄,而是保護數據文件和日志文件的。在一個數據庫上的TDE執行對于連接到所選數據庫的應用程序來說是非常簡單而透明的。它不需要對現有應用程序做任何改變。這個保護是應用于數據文件和日志文件以及備份文件的。一旦在一個數據庫上激活了TDE,備份恢復到另一個SQL Server實例或附加數據文件到另一個SQL Server實例上去將是不允許的,除非用來保護數據庫加密密鑰(DEK)的證書是可用的。
TDE的加密特性是應用于頁面級別的。一旦激活了,頁面就會在它們寫到磁盤之前加密,在讀取到內存之前解密。有一點一定要記住,那就是SQL Server和客戶端應用程序之間的通信渠道沒有通過TDE來保護和加密。
下圖顯示了SQL Server怎樣使用TDE加密一個數據庫:
透明數據加密使用一個數據加密密鑰(DEK)用于加密數據庫,它存儲在數據庫啟動記錄中。DEK由一個存儲在主數據庫中的證書來保護??蛇x的,DEK可以由一個放置在硬件安全模塊(HSM)中的非對稱密鑰以及外部密鑰管理(EKM)的支持來保護。證書的私鑰由對稱密鑰的數據庫主密鑰來加密,它通常由一個強密碼來保護。注意,盡管這個證書可以由一個密碼來保護,但是TDE要求這個證書由數據庫主密鑰來保護。數據庫主密鑰由服務主密鑰來保護,而服務主密鑰由數據保護API來保護。
TDE的執行
如同上面所提到的,TDE的執行相對簡單。下面是一個示例腳本,它使得在一個叫做TestDatabase的數據庫上激活了TDE?!?/p>
-- If the master key is not available, create it. USE master; GO IF NOT EXISTS (SELECT * FROM sys.symmetric_keys WHERE name LIKE '%MS_DatabaseMasterKey%') BEGIN CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Pa$$w0rd4545'; END GO -- Create the certificate in the master database. USE master; GO -- Since ENCRYPTION BY PASSWORD is not mentioned, the private key of the certificate -- will be encrypted by database master key created above. IF NOT EXISTS (SELECT * FROM sys.certificates WHERE name LIKE '%DEKCertificate%') BEGIN CREATE CERTIFICATE DEKCertificate WITH SUBJECT = 'DEK Certificate' END GO -- Create Database Encryption Key (DEK) in the user database USE TestDatabase GO IF NOT EXISTS (SELECT * FROM sys.dm_database_encryption_keys WHERE database_id = DB_ID('TestDatabase')) BEGIN CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_128 ENCRYPTION BY SERVER CERTIFICATE DEKCertificate END GO -- Check whether the key is created SELECT DB_NAME(database_id) AS DatabaseName, * FROM sys.dm_database_encryption_keys -- This should return one row (or more if DEKs have been generated in other databases) -- with the encryption_state of 1 (1 = unencrypted). -- Set the DEK on in the TestDatabase. ALTER DATABASE TestDatabase SET ENCRYPTION ON GO -- Check whether the encryption_state is changed to 3. It should be. SELECT DB_NAME(database_id) AS DatabaseName, * FROM sys.dm_database_encryption_keys |
前兩個步驟顯示了怎樣創建主數據庫中的數據庫主密鑰和證書。注意,ENCRYPTION BY PASSWORD 不是由CREATE CERTIFICATE 來指定,因此自簽名的證書的私鑰將由數據庫主密鑰來保護。下一步顯示了在TestDatabase中創建DEK的方法。執行這個代碼。它添加了DEK到TestDatabase。如果這個證書的私鑰由一個密碼保護,那么你將獲得如下所示的錯誤信息:
Msg 33101, Level 16, State 1, Line 4
不能使用證書“DEKCertificateTest”,因為它的私鑰沒有顯示出來或者它不是由數據庫主密鑰來保護的。SQL Server 需要自動訪問這個操作所使用證書的私鑰的能力。
sys.dm_database_encryption_keys 使你可以看到DEK被添加到服務器上。字段encryption_state 表示DEK是處于下面的哪個狀態:沒有加密、加密中、已加密、密鑰改變中、和解密中,這些各自對應1、2、3、4、和5這幾個數值。當你在設置ENCRYPTION之前運行DMV時,這個狀態將顯示為1,如果設置了,這個狀態將顯示為3。完成了?,F在TestDatabase 已經是完全安全的了。
我的數據庫現在是安全的嗎?
盡管我們成功地使得在我們的數據庫上激活了TDE,但是我們還需要確保它在所有級別都是安全的。我們將在這方面做兩個測試。首先,我們將備份這個數據庫并嘗試恢復這個備份到另一個SQL Server 2008實例上去。這個恢復操作一定會失敗的,除非這個證書用于保護DEK的私鑰是可用于主數據庫的。第二,我們將嘗試在另一個實例中附加TestDatabase的mdf和ldf文件。它應該也不能起作用。這是用于測試的代碼:
-- First step is backing up the TestDatabase. BACKUP DATABASE [TestDatabase] TO DISK = N'E:\TestDatabaseFull.bak' WITH NOFORMAT, NOINIT, NAME = N'TestDatabase-Full Database Backup' GO -- Now connect with another SQL Server 2008 instance. -- Try to restore the backup we have taken, in the new instance. -- This statement should be failed. RESTORE DATABASE [TestDatabase] FROM DISK = N'E:\TestDatabaseFull.bak' WITH FILE = 1, MOVE N'TestDatabase' TO N'D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\TestDatabase.mdf', MOVE N'TestDatabase_log' TO N'D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\TestDatabase_log.ldf', NOUNLOAD, STATS = 10 GO |
第一個步驟備份了這個數據庫。第二部分需要運行在一個不同的SQL Server 2008實例上。當你嘗試在一個不同的SQL Server 2008實例中恢復這個備份時,你將得到一個類似于下面所示的錯誤信息:
10 percent processed. 20 percent processed. 31 percent processed. 41 percent processed. 52 percent processed. 62 percent processed. 73 percent processed. 83 percent processed. 94 percent processed. 100 percent processed. Msg 33111, Level 16, State 3, Line 1 Cannot find server certificate with thumbprint '0x8AD8C0A89476752FCC3D7A7005A2DCF546C38C58'. Msg 3013, Level 16, State 1, Line 1 RESTORE DATABASE is terminating abnormally. |
當你嘗試將這個數據庫附加到另一個實例中去時你將面對相同的問題。
USE [master] GO CREATE DATABASE [TestDatabase] ON ( FILENAME = N'D:\Test\TestDatabase.mdf'), ( FILENAME = N'D:\Test\TestDatabase_log.ldf') FOR ATTACH GO |
上面代碼的結果是:
Msg 33111, Level 16, State 3, Line 1
Cannot find server certificate with thumbprint '0x8AD8C0A89476752FCC3D7A7005A2DCF546C38C58'.
它起作用了。我們的數據庫是安全的了?;謴突蚋郊覶estDatabase 到另一個實例中去的唯一方法是在第二個實例中添加相同的證書。學習下面的代碼:
-- backup the certificate -- The private key will be encrypted by the password specified BACKUP CERTIFICATE DEKCertificate TO FILE = 'E:\DEKCertificate.cert' WITH PRIVATE KEY ( FILE = 'E:\Instance1PrivateKey.key', ENCRYPTION BY PASSWORD = 'Pa$$w0rd5454' ) -- create the certificate in the second instance by using the backup -- Private key will be loaded from the saved file. USE [master] GO CREATE CERTIFICATE DEKCertificate FROM FILE = 'E:\DEKCertificate.cert' WITH PRIVATE KEY ( FILE = 'E:\Instance1PrivateKey.key' , DECRYPTION BY PASSWORD = 'Pa$$w0rd5454' ) |
這個代碼的第一部分將這個證書備份到了一個文件中。它還備份了這個證書的私鑰。代碼中指定的密碼是用于加密私鑰的。代碼的第二部分需要運行在第二個SQL Server 2008實例上。它使用備份證書創建了一個證書。當這個代碼運行后,你將可以恢復或附加TestDatabase數據庫到新的實例中去。
在激活TDE之前需要考慮什么?
在你在數據庫上激活TDE之前只有很少的事情需要注意,那就是:
TDE是否影響所執行的災難復原計劃?
設想一個簡單的災難復原計劃,備份和恢復。你可能開發了這個計劃而且它執行沒有任何問題。你激活了TDE,仍然沒有問題,時間表作業備份了你的數據庫。假設這個服務器開始產生嚴重錯誤導致你需要重新安裝操作系統和SQL Server。你可能不做它想就輕松地重新安裝,因為你有數據庫備份。當數據庫恢復時問題出現了。你可能具有不是加密格式的數據庫完全備份,你可能有一些在激活TDE之后進行的事務型備份,所以它們是加密的。你沒有用于TDE的證書備份。這導致你處于一個不可預料的境地。因為你沒有所用證書的備份,所以你將不能恢復事務型備份。
想想在激活TDE之前災難復原計劃的開發。如果你有計劃,那么確保這個計劃在激活TDE之后仍然可用。這不只用于備份和恢復策略,它還用于其它計劃,例如日志傳送和數據庫鏡像。
在你的數據庫中有只讀文件組嗎?
如果數據庫有只讀文件組,那么TDE將會失敗。一旦TDE激活了,那么encryption_state的數值將永遠不可能是3(加密的)而是2(加密中)。SQL Server在運行TDE代碼時不會拋出任何異常。激活TDE之后,如果你打開數據庫的屬性窗口,你將會發現屬性Encryption Enabled的值被設為了true。使用下面的代碼進行測試:
-- create a new database for testing TDE on readonly file groups USE master GO CREATE DATABASE [TestDatabase2] ON PRIMARY ( NAME = N'TestDatabase2_Primary', FILENAME = N'E:\TestDatabase2_Primary.mdf' , SIZE = 3072KB , FILEGROWTH = 1024KB ), FILEGROUP [FG1_Default] ( NAME = N'TestDatabase2_FG1', FILENAME = N'E:\TestDatabase2_FG1.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ), FILEGROUP [FG2_ReadOnly] ( NAME = N'TestDatabase2_FG2', FILENAME = N'E:\TestDatabase2_FG2.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) LOG ON ( NAME = N'TestDatabase2_log', FILENAME = N'E:\TestDatabase2_log.ldf' , SIZE = 1024KB , FILEGROWTH = 10%) GO -- Set the FG1_Default file group as the default one. -- Add a table to the default file group -- Add a table to the FG2_ReadOnly file group -- Set the file group FG2_ReadOnly file group as READONLY -- Create Database Encryption Key (DEK) in the user database -- Enable TDE on the database |
首先這個代碼創建了一個具有三個數據文件的數據庫,這三個文件叫做TestDatabase2_Primary、TestDatabase2_FG1和TestDatabase2_FG2。文件組FG1_Default 設置為默認文件組,在其中創建了TestTable1。在FG2_ReadOnly文件組中創建了TestTable2。然后FG1_ReadOnly文件組被標識為READONLY。
最后,在TestDatabase2 中創建了DEK,Encryption屬性設置為true。所有的語句都成功執行。如果你查詢sys.dm_database_encryption_keys,你將看到TestDatabase2的encryption_state是2,這表示加密結束了但沒有完成。
是否使用了FileStream數據類型?
使用了filestream類型的數據庫可以使用TDE來進行加密,但是文件流數據不會被加密。
當激活TDE之后會影響什么?
在一個數據庫上激活TDE會影響以下事情:
事務日志
一旦TDE激活了,SQL Server 通過將文本數據清理出去從而確保日志文件不包含文本數據。SQL Server 從具有加密格式的新VLF開始。
TEMPDB系統數據庫
當你在任何數據庫上激活了TDE之后這將會自動加密。這會導致使用tempdb數據庫的非加密數據庫性能下降。
日志傳送和數據庫鏡像
如果你在一個傳送日志到另一個數據庫的數據庫(意味著激活了日志傳送的數據庫)上激活了TDE,那么日志傳送操作將會在輔助數據庫上失敗,除非在輔助服務器上證書可用。
壓縮備份
下面是在一個激活了TDE的數據庫上進行壓縮備份的測試,看起來在激活TDE的數據庫上壓縮并不怎么高效:
-- create a new database for testing compressed backup on TDE enabled database -- Create a table and insert some records -- Backup the TestDatabase3 without compressing it -- Backup the TestDatabase3 with compression -- Now enable TDE on this -- Backup the TestDatabase3 again (after TDE enabled) without compressing it -- Backup the TestDatabase3 with compression |
這個代碼創建一個數據庫并插入一些記錄到數據表中。然后這個數據庫被備份兩次,一次沒有壓縮另一次有壓縮。然后你需要在這個數據庫上激活TDE并執行其它的與激活TDE之前備份所使用的相同代碼。備份文件規模是:
在激活TDE之前完全備份1,365 KB
在激活TDE之前有壓縮的完全備份124KB
激活TDE之后的完全備份1,365 KB
激活TDE之后有壓縮的完全備份 1,278 KB
你可以看到它們的不同。結果證明激活了TDE的數據庫的壓縮備份文件不那么高效。