簡介
加密是指通過使用密鑰或密碼對數據進行模糊處理的過程。在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.創建數據庫主密鑰
數據庫主密鑰由代碼1所示的密碼和服務主密鑰共同保護。當數據庫主密鑰創建成功后,我們就可以使用這個密鑰創建對稱密鑰,非對稱密鑰和證書了。如代碼2所示。
--創建證書 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所示。
--由證書加密對稱密鑰 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所示。
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所示。
--打開之前創建的由證書加密的對稱密鑰 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所示。
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所示。
--基於我們之前創建的證書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提供的加密技術之前,一定要先對加密的各個功能概念有一個系統的了解,否則很有可能造成的后果是打不開數據庫。准備在后續文章中再寫關於證書,密鑰的備份和恢復….