簡介
加密是指通過使用金鑰或密碼對資料進行模糊處理的過程。在SQL Server中,加密並不能替代其他的安全設定,比如防止未被授權的人訪問資料庫或是資料庫例項所在的Windows系統,甚至是資料庫所在的機房,而是作為當資料庫被破解或是備份被竊取後的最後一道防線。通過加密,使得未被授權的人在沒有金鑰或密碼的情況下所竊取的資料變得毫無意義。這種做法不僅僅是為了你的資料安全,有時甚至是法律所要求的(像國內某知名IT網站洩漏密碼這種事在中國可以道歉後不負任何責任了事,在米國妥妥的要破產清算)。
SQL Server中的加密簡介
在SQL Server2000和以前的版本,是不支援加密的。所有的加密操作都需要在程式中完成。這導致一個問題,資料庫中加密的資料僅僅是對某一特定程式有意義,而另外的程式如果沒有對應的解密演算法,則資料變得毫無意義。
到了SQL Server2005,引入了列級加密。使得加密可以對特定列執行,這個過程涉及4對加密和解密的內建函式
SQL Server 2008時代,則引入的了透明資料加密(TDE),所謂的透明資料加密,就是加密在資料庫中進行,但從程式的角度來看就好像沒有加密一樣,和列級加密不同的是,TDE加密的級別是整個資料庫。使用TDE加密的資料庫檔案或備份在另一個沒有證照的例項上是不能附加或恢復的。
加密的一些基礎知識
加密是指通過使用金鑰或密碼對資料進行模糊處理的過程。加密解密最簡單的過程如圖1所示。
圖1.一個簡單的加密解密過程
通常來說,加密可以分為兩大類,對稱(Symmetric)加密和非對稱(Asymmetric)加密。
對稱加密是那些加密和解密使用同一個金鑰的加密演算法,在圖1中就是加密金鑰=解密金鑰。對稱加密通常來說會比較羸弱,因為使用資料時不僅僅需要傳輸資料本身,還是要通過某種方式傳輸金鑰,這很有可能使得金鑰在傳輸的過程中被竊取。
非對稱加密是那些加密和解密使用不同金鑰的加密演算法,在圖1中就是加密金鑰!=解密金鑰。用於加密的金鑰稱之為公鑰,用於解密的金鑰稱之為私鑰。因此安全性相比對稱加密來說會大大提高。當然有一長必有一短,非對稱加密的方式通常演算法會相比對稱金鑰來說複雜許多,因此會帶來效能上的損失。
因此,一種折中的辦法是使用對稱金鑰來加密資料,而使用非對稱金鑰來加密對稱金鑰。這樣既可以利用對稱金鑰的高效能,還可以利用非對稱金鑰的可靠性。
加密演算法的選擇
現在流行的很多加密演算法都是工業級的,比如對稱加密的演算法有:DES、3DES、IDEA、FEAL、BLOWFISH.而非對稱加密的演算法比如經典的RSA。因為這些演算法已經公佈了比較長的時間,並且經受了很多人的考驗,所以通常來說都是比較安全的。
SQL Server提供了比如:DES、Triple DES、TRIPLE_DES_3KEY、RC2、RC4、128 位 RC4、DESX、128 位 AES、192 位 AES 和 256 位 AES這些加密演算法,沒有某種演算法能適應所有要求,每種演算法都有長處和短處,關於每種加密演算法的細節,請Bing…
但選擇演算法有一些共通之處:
- 強加密通常會比較弱的加密佔用更多的 CPU 資源。
- 長金鑰通常會比短金鑰生成更強的加密。
- 非對稱加密比使用相同金鑰長度的對稱加密更強,但速度相對較慢。
- 使用長金鑰的塊密碼比流密碼更強。
- 複雜的長密碼比短密碼更強。
- 如果您正在加密大量資料,應使用對稱金鑰來加密資料,並使用非對稱金鑰來加密該對稱金鑰。
- 不能壓縮已加密的資料,但可以加密已壓縮的資料。如果使用壓縮,應在加密前壓縮資料。
SQL Server中的加密層次結構
在SQL Server中,加密是分層級的.根層級的加密保護其子層級的加密。概念如圖2所示。
圖2.SQL Server加密的層級
由圖2可以看出,加密是分層級的。每一個資料庫例項都擁有一個服務主金鑰(Service Master Key),對應圖2中的橙色部分。這個金鑰是整個例項的根金鑰,在例項安裝的時候自動生成,其本身由Windows提供的資料保護API進行保護(Data Pertection API),服務主金鑰除了為其子節點提供加密服務之外,還用於加密一些例項級別的資訊,比如例項的登入名密碼或者連結伺服器的資訊。
在服務主金鑰之下的是資料庫主金鑰(Database Master Key),也就是圖2中土黃色的部分,這個金鑰由服務主金鑰進行加密。這是一個資料庫級別的金鑰。可以用於為建立資料庫級別的證照或非對稱金鑰提供加密。每一個資料庫只能有一個資料庫主金鑰,通過T-SQL語句建立,如程式碼1所示。
1 |
CREATE MASTER KEY ENCRYPTION BY PASSWORD ='Pa$ $word' |
程式碼1.建立資料庫主金鑰
資料庫主金鑰由程式碼1所示的密碼和服務主金鑰共同保護。當資料庫主金鑰建立成功後,我們就可以使用這個金鑰建立對稱金鑰,非對稱金鑰和證照了。如程式碼2所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
--建立證照 CREATE CERTIFICATE CertTest with SUBJECT = 'Test Certificate' GO --建立非對稱金鑰 CREATE ASYMMETRIC KEY TestAsymmetric WITH ALGORITHM = RSA_2048 ENCRYPTION BY PASSWORD = 'pa$ $word'; GO --建立對稱金鑰 CREATE SYMMETRIC KEY TestSymmetric WITH ALGORITHM = AES_256 ENCRYPTION BY PASSWORD = 'pa$ $word'; GO |
程式碼2.建立證照,非對稱金鑰和對稱金鑰
在程式碼2中我們看出,並沒有顯式指定使用資料庫主金鑰加密證照,對稱金鑰和非對稱金鑰。這是因為每個資料庫只能有一個資料庫主金鑰,所以無需指定。建立成功後我們可以在SSMS中檢視到剛剛建立的證照,非對稱金鑰和對稱金鑰,如圖3所示。
圖3.檢視剛剛建立成功的證照,非對稱金鑰和對稱金鑰
由這個加密層級不難推斷,如果資料庫主金鑰被破解,則由其所建立的證照,對稱金鑰,非對稱金鑰都有可能被破解。
由圖2的層級我們還可以看出,對稱金鑰不僅僅可以通過密碼建立,還可以通過其它對稱金鑰,非對稱金鑰和證照建立。如程式碼3所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
--由證照加密對稱金鑰 CREATE SYMMETRIC KEY SymmetricByCert WITH ALGORITHM = AES_256 ENCRYPTION BY CERTIFICATE CertTest; GO --由對稱金鑰加密對稱金鑰 OPEN SYMMETRIC KEY TestSymmetric DECRYPTION BY PASSWORD='pa$ $word' CREATE SYMMETRIC KEY SymmetricBySy WITH ALGORITHM = AES_256 ENCRYPTION BY SYMMETRIC KEY TestSymmetric; GO --由非對稱金鑰加密對稱金鑰 CREATE SYMMETRIC KEY SymmetricByAsy WITH ALGORITHM = AES_256 ENCRYPTION BY ASYMMETRIC KEY TestASymmetric; GO |
程式碼3.由幾種不同的加密方式建立對稱金鑰
SQL Server中的資料列加密(Column-level Encryption)
SQL Server在2005引入了列加密的功能。使得可以利用證照,對稱金鑰和非對稱金鑰對特定的列進行加密。在具體的實現上,根據加密解密的方式不同,內建了4對函式用於加密解密:
- EncryptByCert() 和DecryptByCert()—利用證照對資料進行加密和解密
- EncryptByAsymKey() and DecryptByAsymKey()—利用非對稱金鑰對資料進行加密和解密
- EncryptByKey() and DecryptByKey()—利用對稱金鑰對資料進行加密和解密
- EncryptByPassphrase() and DecryptByPassphrase()—利用密碼欄位產生對稱金鑰對資料進行加密和解密
因此,加密資料列使用起來相對比較繁瑣,需要程式在程式碼中顯式的呼叫SQL Server內建的加密和解密函式,這需要額外的工作量,並且,加密或解密的列首先需要轉換成Varbinary型別。
下面我們來看一個例子:
在AdventureWorks示例資料庫中,我們找到Sales.CreditCard表,發現信用卡號是明文顯示的(怎麼AdventureWorks也像洩漏密碼的某IT網站這麼沒節操)。因此希望對這一列進行加密。
圖5.和國內某知名IT網站一樣沒節操的明文儲存重要資訊
首先我們需要將CardNumber列轉為Varbinary型別。這裡通過Select Into新建個表,如程式碼4所示。
1 2 3 4 5 6 7 8 9 |
SELECT CreditCardID, CardType, CardNumber_encrypt = CONVERT(varbinary(500), CardNumber), ExpMonth, ExpYear, ModifiedDate INTO Sales.CreditCard_Encrypt FROM Sales.CreditCard WHERE 1<>1 |
程式碼4.通過Select Into建立新表
此時我們利用之前建立的由證照加密的對稱金鑰來進行列加密,如程式碼5所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
--開啟之前建立的由證照加密的對稱金鑰 OPEN SYMMETRIC KEY SymmetricByCert DECRYPTION BY CERTIFICATE CertTest --利用這個金鑰加密資料並插入新建的表 insert Sales.CreditCard_encrypt ( CardType, CardNumber_encrypt, ExpMonth, ExpYear, ModifiedDate ) select top 10 CardType, CardNumber_encrypt = EncryptByKey(KEY_GUID('SymmetricByCert'), CardNumber), ExpMonth, ExpYear, ModifiedDate from Sales.CreditCard |
程式碼5.利用證照加密過的對稱金鑰加密資料
此時加密列無法直接進行檢視,如圖6所示:
圖6.無法直接檢視加密的列
此時可以通過對應的解密函式檢視資料,如程式碼6所示。
1 2 3 4 5 6 7 8 9 |
OPEN SYMMETRIC KEY SymmetricByCert DECRYPTION BY CERTIFICATE CertTest select CardType, CardNumber = convert(nvarchar(25), DecryptByKey(CardNumber_encrypt)), ExpMonth, ExpYear, ModifiedDate from Sales.CreditCard_encrypt |
程式碼6.由對應的解密函式檢視加密的資料
所得到的結果如圖7所示。
圖7.解密後結果可以正確顯示
利用非對稱金鑰和證照進行加密解密只是函式不同,這裡就不測試了。
透明資料加密(Transparent Data Encryption)
在SQL Server 2008中引入了透明資料加密(以下簡稱TDE),之所以叫透明資料加密,是因為這種加密在使用資料庫的程式或使用者看來,就好像沒有加密一樣。TDE加密是資料庫級別的。資料的加密和解密是以頁為單位,由資料引擎執行的。在寫入時進行加密,在讀出時進行解密。客戶端程式完全不用做任何操作。
TDE的主要作用是防止資料庫備份或資料檔案被偷了以後,偷資料庫備份或檔案的人在沒有資料加密金鑰的情況下是無法恢復或附加資料庫的。
TDE使用資料加密金鑰(DEK)進行加密。DEK是存在Master資料庫中由服務主金鑰保護,由的保護層級如圖8所示。
圖8.TDE的加密層次
開啟TDE的資料庫的日誌和備份都會被自動加密。
因為TDE使得資料庫在寫入時加密,在讀出時解密,因此需要額外的CPU資源,根據微軟的說法,需要額外3%-5%的CPU資源。
下面我們來看如何開啟TDE
開啟TDE非常簡單,只需建立資料加密金鑰(DEK)後,將加密選項開啟就行,如程式碼7所示。
1 2 3 4 5 6 7 8 9 10 11 |
--基於我們之前建立的證照CertTest,建立DEK --CertTest需要在Master資料庫中 USE AdventureWorks GO CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_256 ENCRYPTION BY SERVER CERTIFICATE CertTest GO --開啟TDE ALTER DATABASE AdventureWorks SET ENCRYPTION ON |
程式碼7.建立DEK後,開啟TDE
這裡值得注意的是,DEK是存在所開啟TDE的資料庫中的。當然,這個操作我們也可以通過在SSMS中右鍵點選需要開始TDE的資料庫,選擇任務–管理資料庫加密來進行。如圖9所示。
圖9.在SSMS中開啟TDE
開啟TDE後,我們可以通過圖10的語句檢視TDE的狀態。
圖10.檢視資料庫加密狀態
總結
本文介紹了加密的基本概念,SQL Server中加密的層級,以及SQL Server中提供的兩種不同的加密方式。SQL Server的TDE是一個非常強大的功能,在使用者程式中不做任何改變就能達到資料庫層面的安全。在使用SQL Server提供的加密技術之前,一定要先對加密的各個功能概念有一個系統的瞭解,否則很有可能造成的後果是打不開資料庫。準備在後續文章中再寫關於證照,金鑰的備份和恢復….