在保密你的伺服器和數據,防備當前複雜的攻擊,SQL Server有你需要的一切。但在你能有效使用這些安全功能前,你需要理解你面對的威脅和一些基本的安全概念。這篇文章提供了基礎,因此你可以對SQL Server里的安全功能充分利用,不用在面對特定威脅,不能保護你數據的功能上浪費時間。 從讓人眼花繚亂的 ...
在保密你的伺服器和數據,防備當前複雜的攻擊,SQL Server有你需要的一切。但在你能有效使用這些安全功能前,你需要理解你面對的威脅和一些基本的安全概念。這篇文章提供了基礎,因此你可以對SQL Server里的安全功能充分利用,不用在面對特定威脅,不能保護你數據的功能上浪費時間。
從讓人眼花繚亂的客戶端使用連接,通過到處分佈的網路,尤其是互聯網,關係資料庫在各種應用程式里廣泛使用。這使數據對任何人,在任何地方都可訪問。資料庫可以保存人類知識的很大部分,包括高度敏感的個人信息和讓國際商務工作的關鍵數據。
對於想要偷取數據或通過篡改數據來傷害數據的擁有者的 人來說,這些功能使資料庫成為有吸引力的目標。確保你的數據安全是SQL Server配置和使用它來保存數據的程式的重要部分。這個系列會探尋SQL Server 2012安全的基本,這樣的話你可以保護你的數據和伺服器資源,按你需要的安全等級來保護數據,免受這些威脅對你數據的影響。大部分信息對SQL Server的早期版本也適用,回到SQL Server 2005也可以,因為那是微軟在產品里徹底檢查安全的時候。但我也會談論只在SQL Server 2012和後續版本里才有的功能。
一個重要的安全概念是深度防禦,這就是說最好的安全分層保護而不是單靠一層保護。在你的網路,伺服器,SQL Server實例,資料庫都做了安全防護後,你可以添加最後一個通過加密敏感數據的強大數據保護層。這篇文章會探尋通過加密的資料庫保護,同時包括數據在網路傳輸或記憶體里,和在表裡休息。你會學到加密密匙的層級和你可以用來加密數據的各種密匙,還有你如何管理密匙,讓伺服器為你服務。
數據加密
到目前為止,你學習了SQL Server內建的很多強大安全功能,你可以用來保護你的數據和其它資料庫對象。當你把這些和強大的網路完全結合,例如防火牆,最小特權用戶賬號和其它工具,你的數據應該非常安全,是不是?
答案還是不安全。雖然SQL Server 2012和SQL Server 2014目前已經是最安全的了(現在已經有SQL Server 2016了)——假設你充分並有效使用了安全功能——成功的攻擊還是可能的。黑客是聰明的,因此很有可能會有某些人,在某個時間,找出黑入你資料庫伺服器的方法,並訪問你的數據。即使你有100%的自信,這樣的攻擊還是可能的,你會在內部攻擊的接收端發現自己——信任的員工做壞事了。
可以幫你理解為你的數據和你需要保護的其它資源,如何獲得安全的最高級別的安全主體是深度防禦。深度防禦意味著你從未依賴於單個手段來保護任何有價值的。你加入層層不同的安全,這樣的話,任何攻擊者在拿到你的數據前,需要突破多個困難障礙。
這也是很多中世紀的城堡有個護城河作為第一道防線,裡面有很多討厭的動物在游泳。接下來一層是戒備森嚴,厚的的橡木門和幾米厚的石牆。經常有另一個厚的,戒備森嚴的牆在外牆裡。層層安全保護著裡面的人和寶藏。
同樣的方法,SQL Server有很多層安全,它有很多來建造和維護它們。但當你的數據是極其寶貴時,你可以加最後一層防護:加密。
SQL Server 2015是第一個豐富支持數據加密的版本,自那後的每個版本都做了一些改進。你可以使用各種加密類型,包括各種加密密匙,可以秘密傳輸數據為看不懂的胡言亂語,除非用戶有密匙來解密。SQL Server支持各類加密演算法。而且最重要的是,你可以讓伺服器來做管理密匙和的保持它們絕密的所有工作,這是加密最困難的部分。
提示:
加密是極其密集處理的操作,因為它需要複雜的計算。現代的電腦設備都很快,對於包含75個加密列,有1億條數據的表,完成計算需要多個處理能力,對於設計不好的查詢,你會有巨大的負擔,會把動力不足的伺服器累趴。使用加密來保護只值得終層保護的數據。
加密密匙(Encryption keys)
SQL Server允許使用三種加密密匙的任何之一。加密密匙是小塊數據,當插入到演算法後,轉化數據為密文,這個密文如果沒有正確的加密密匙,通常不能轉為明文。
- 非對稱密匙(Asymmetric Key):這種加密類型使用匹配的公共/私有密匙。一個密匙來加密數據,另一個解密它。你可以和任何人共用公共密匙,這樣他們就加密任何數據,只有你才可以使用私密密匙來解密。SQL Server使用長度512、1024 或 2048 位私密密匙的RSA加密演算法。關於這個演算法,可以參考下維基百科。
- 對稱密匙(Symmetric Key):在這個加密類型里,加密和解密數據的密匙數據是一樣的。這有時被稱為公有密匙,因為雙方共用數據必須有相同的密匙。在某些情況下,很難使用對稱密匙,因為安全傳輸秘密從一個地方到另一個地方是個問題。對稱密匙在資料庫里使用是個好主意,因為他們從未離開資料庫。SQLServer支持RC4,RC2演算法,也支持DES,AES演算法家族。你可以在這個網站瞭解這些演算法的概要信息。
提示:
微軟在SQL Server 2012里已經明智的取消了RC4對稱密匙,只有資料庫的相容級別為90或100(SQL Server 2005和SQL Server2008)才可以,這是為了保持向後相容。RC4有很多弱點,最重要的是演算法不散列話密匙——在加密前加些隨機的文本到明文——這樣在同樣的密文裡加密值是重覆的。這讓解密比應該有的難度更簡單。即使你維護SQL Server的老版本,也不要使用RC4!
- 證書(Certificate):證書是對公共密匙的數字封裝,作為非對稱密匙加密的一部分。SQL Server可以為你創建使用的證書,或者你可以使用第三方證書授權。SQL Server使用互聯網工程任務組(Internet Engineering Task Force)的X.509規格。
SQL Server使用如下的加密密匙層級,如插圖8.1所示,來加密和保護你存儲在資料庫里的密匙。
插圖8.1:加密密匙層級
在伺服器級別,SQL Server的每個實例有個服務主密匙(Service Master Key),你用來加密低一層的其它密匙。這個密匙在SQL Server實例安裝時創建。你可以備份和還原它,如果它已經泄露的話,也可以重新生成它,但絕大部分時間你可以不理會它。SQL Server會為你管理它,你也從不會直接使用它。服務主密匙在系統底層存儲並保護,使用Windows數據保護API或DPAPI。
服務主密匙有一些內部使用,但我們這裡的目的是SQL Server用它來加密和保護你創建的任何資料庫主密匙(Database Master Keys)。在你加密的任何資料庫里都需要資料庫主密匙。它是加密和保護任何你創建密匙的對稱密匙。你需要在資料庫上下文里使用代碼8.1的語句創建它。
1 USE EncryptionDB; 2 GO 3 4 CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'gK#3hbQKDFQY0oF';
代碼8.1:在EncryptionDB資料庫里創建一個資料庫主密匙的代碼
提示:
如果你沒有按這個系列文章逐篇閱讀的話,你可以執行下列代碼來初始化測試環境。
1 -- *** Beginning of setup code *** 2 -- ******************************* 3 4 -- Set up sample encryption database 5 USE master; 6 GO 7 8 -- Set up a login 9 IF SUSER_SID('User1') IS NOT NULL DROP LOGIN User1; 10 CREATE LOGIN User1 WITH password = '3f@$fWDY3QvP&K0'; 11 GO 12 13 IF DB_ID('EncryptionDB') IS NOT NULL DROP DATABASE EncryptionDB; 14 CREATE DATABASE EncryptionDB; 15 GO 16 USE EncryptionDB; 17 GO 18 19 CREATE USER User1 FOR LOGIN User1; 20 21 CREATE TABLE Customer ( 22 CustId int, 23 Name nvarchar(30), 24 City varchar(20), 25 CreditCardType varbinary(1000), 26 CreditCardNumber varbinary(1000), 27 Notes varbinary(4000)); 28 GO 29 30 -- Grant access on the table to user 31 GRANT SELECT, INSERT ON Customer to User1; 32 33 -- *** End of setup code *** 34 -- *************************
資料庫主密匙保存2次:服務主密匙加密一次並保存,用你提供的密碼再次加密。你可以移除其中一個,但不能同時移除。通常我們都2個都保留。
作為對稱密匙,資料庫主密匙在你使用它之前必須打開。打開密匙把它載入記憶體並解密它,這樣就可以使用了。因為伺服器的服務主密匙加密資料庫主密匙,SQL Server可以Wie你自動打開密匙,這樣的話你基本不需要直接打開它。想服務主密匙,你可以備份和還原它,想要的話也可以修改它。
你會使用插圖8.1里的其它密匙來加密數據。箭頭表示你用來加密和保護其它密匙的密匙。例如,你可以使用數據主密匙來加密其它證書或對稱密匙。證書和非對稱密匙只能保護對稱密匙,對稱密匙可以被證書,非對稱密匙和其它對稱密匙保護。
密匙管理
插圖8.1戰士了加密密匙的其它方面:你可以使用任何另一個密匙或密碼來創建任何密匙。這個稱為密匙管理,這是SQL Server可以為你處理一個主要服務。
密匙管理最困難的一部分選擇正確的加密。歷史上有很多密匙被攔截後,有很多國家秘密被破解。在二戰期間,美國、英國和其它聯盟國家把大量資源放入截取德國和日本的加密密匙,這樣的話,他們可以截取並得到高機密的信息。在最近,很多安全性的應用程式被瓦解,因為攻擊能找到在應用程式里或電腦上嵌入的密匙。安全共用秘密非常困難。
你可以自己管理SQL Server加密密匙,如果你選擇使用密碼,那秘密保存好密匙就是你的責任。大多數人不想這樣做,因為它需要高度專業的技術技能。但如果你想承擔任務,當你創建密匙時直接使用密碼選項。密碼就是基本的密匙,你要確保你可以安全的地方保存這個密匙,當你需要它的時候,可以密碼傳輸它。
但你沒必要處理這些細節,因為SQL Server會為你管理好密匙。它會為你加密新的密匙,使用你指定的任何方法作為CREATE語句的一部分,安全保存數據如同它保存任何敏感信息。
你有管理密匙的選項,但沒事就不要亂動。
加密數據
現在我們來看一個在SQL Server裡加密的一個例子。在這個場景里,Customer表有一些客戶的常規信息。一些信息,例如客戶名稱和它們所在的城市,不是敏感的數據,不值得加密。其它數據,例如信用卡類型和號碼及備註會包含特定敏感的個人信息,需要加密。
你會使用對稱密匙來加密表的數據,但記住對稱密匙需要資料庫里一個證書或非對稱密匙來保護它。因此,首先使用代碼8.2來創建保護對稱密匙的非對稱密匙。
1 CREATE ASYMMETRIC KEY User1AsymmetricKey 2 AUTHORIZATION User1 3 WITH ALGORITHM = RSA_2048
代碼8.2:創建使用RSA 2048位演算法,屬於User1的非對稱密匙。
非對稱密匙稱為User1AsymmetricKey,AUTHORIZATION子句指定User1擁有密匙。這個密匙使用2048位的RSA加密,非常強的加密。這個必須是真的,真的重要數據!
接下來,使用代碼8.3出阿健對稱密匙User1SymmetricKey。(你必須為你的密匙取更有描述性的名稱!)。在這個例子里,它使用TRIPLE_DES演算法,用你剛創建的非對稱密匙保護它。
1 CREATE SYMMETRIC KEY User1SymmetricKey 2 WITH ALGORITHM = TRIPLE_DES 3 ENCRYPTION BY ASYMMETRIC KEY User1AsymmetricKey;
代碼8.3:創建使用Triple DES演算法的對稱密匙,用剛纔的非對稱密匙。
如果你想在資料庫列出對稱的加密密匙,你可以使用sys.symmetric_keys目錄視圖來查看它們。代碼8.4生成瞭如插圖8.2所示的結果。註意,因為資料庫主密匙是對稱密匙,他在列表裡也顯示了,你可以看到它用AES_256加密的。
1 SELECT * FROM sys.symmetric_keys;
代碼8.4:在資料庫列出對稱密匙
插圖8.2:查看 sys.symmetric_keys目錄視圖
代碼8.5展示了EncryptionDB資料庫里的表結構。(這個創建表的代碼和剛纔初始化環境代碼是一樣的):
1 CREATE TABLE Customer ( 2 CustId int, 3 Name nvarchar(30), 4 City varchar(20), 5 CreditCardType varbinary(1000), 6 CreditCardNumber varbinary(1000), 7 Notes varbinary(4000));
代碼8.5:創建Customer表,varbinary欄位用來加密數據。
註意,因為最後三個欄位會包含位元組流的原始字元數據的加密數據,欄位類型是varbinary類型。欄位長度取決於數據的大小和保護它的演算法。資料庫有User1用戶,它在表上有SELECT和INSERT許可。
最後,是時候加密一些數據了,我們忘表裡插入一些數據。第一步使用如代碼8.6的語句打開對稱密匙。這一步讓SQL Server從內部獲得密匙,請確定用戶有用這個密匙的許可,然後解密密匙到記憶體就可以開始使用了。
1 OPEN SYMMETRIC KEY User1SymmetricKey 2 DECRYPTION BY ASYMMETRIC KEY User1AsymmetricKey;
代碼8.6:第一步使用對稱密匙,使用OPEN SYMMETRIC KEY打開它
數據加密使用T-SQL的EncryptByKey函數,它生成唯一的GUID來標識密匙。你可以使用Key_GUID函數來獲得GUID,而不必自己直接傳入值。代碼8.7是常規的T-SQL插入語句,往表裡插入一些數據。
1 INSERT INTO Customer VALUES (1, 'Sally Roe', 'Chatinika', 2 EncryptByKey(Key_GUID('User1SymmetricKey'), 'Visa'), 3 EncryptByKey(Key_GUID('User1SymmetricKey'), '1234-5678-9009-8765'), 4 EncryptByKey(Key_GUID('User1SymmetricKey'), 5 'One of our best customers. Treat like royalty.'));
代碼8.7:插入加密數據到表,使用EncryptByKey和Key_GUID函數。
最後一步是關閉對稱密匙,使用代碼8.8。這個會從記憶體移除密匙,釋放這些資源給其它用戶。你應該經常在用完後就關閉密匙,因為它留在記憶體里的話,就會被不小心被攻擊者利用。
1 CLOSE SYMMETRIC KEY User1SymmetricKey;
代碼8.8:CLOSE SYMMETRIC KEY語句關閉密匙,從記憶體中移除它。
提示:
如果你要在批處理里使用加密和解密很多數據,可以留著它打開。打開和關閉密匙需要一點處理,這樣的話你可以更高效。但不要忘記關閉它在你完成的時候!
現在運行SELECT語句看看表裡有什麼,如插圖8.3所示。你可以看到在沒加密欄位看到明文,但加密欄位是隨機的位元組流數據。你的數據現在是安全的!
插圖8.3:在表裡存儲的加密數據。
在表裡的數據是毫無用處的,除非有方法取出它。在這個例子里,你需要使用常規的SELECT語句,使用DecryptByKey函數來解密數據。這個函數返回varbinary數據,以為加密數據可以是任何數據類型。因此獲得原始文本需要DecryptByKey函數的轉化結果為合適的文本字元。
代碼8.9打開密匙,運行SELECT語句。
1 OPEN SYMMETRIC KEY User1SymmetricKey 2 DECRYPTION BY ASYMMETRIC KEY User1AsymmetricKey; 3 SELECT CustID, Name, City, 4 CONVERT(VARCHAR, DecryptByKey(CreditCardType)) AS CardType, 5 CONVERT(VARCHAR, DecryptByKey(CreditCardNumber)) AS CardNumber, 6 CONVERT(VARCHAR, DecryptByKey(Notes)) AS Notes 7 FROM Customer; 8 CLOSE SYMMETRIC KEY User1SymmetricKey;
代碼8.9:打開對稱密匙,然後使用DecryptByKey函數的SELECT語句獲得加密數據
這會顯示如插圖8.4的結果。
插圖8.4:使用SELECT和DecryptByKey後的解密數據
提示:
相同的EncryptByAsymKey,EncryptByCert和其它方法都可以用作其它密匙,都有對應的Decrypt函數。
小結
SQL Server的數據加密功能為你的數據提供了額外一層保護,給你在全面的深度保護。像老的中世紀城堡有多層的要塞,SQL Server攻擊者需要突破網路安全,伺服器安全,SQL Server實例安全和資料庫安全才可以拿到你的數據。然後,勝利就在眼前,它們還要處理數據強悍加密來拿到有用的數據。加上強悍的資料庫安全,使用細微度的許可來提供最小特權,讓主體只能訪問它們需要的數據,你可以為你最敏感的數據建立堅不可摧的保護。
原文鏈接:
http://www.sqlservercentral.com/articles/Stairway+Series/123777/