SQL數據庫加密方式及實例
從2005開始提供了數據庫層面的數據加密與解密。其實現方式主要有以下:
1、 利用CONVERT改變編碼方式:
利用該函數把文字或數據轉換成VARBINARY。但該方式不具備保護數據的能力,僅避免瀏覽數據的過程中能直接看到敏感數據的作用。
2、 利用對稱密鑰:
搭配EncryptByKey進行數據加密。使用DecryptByKey函數進行解密。這種方式比較適合大數據量。因為對稱密鑰的過程耗用資源較少。
3、 利用非對稱密鑰:
搭配EncryptByAsymKey進行數據加密。使用DecryptByAsymKey函數進行解密。用於更高安全級別的加解密數據。因為耗用資源叫多。
4、 利用憑證的方式:
搭配EncryptByCert進行加密和DecryptByCert函數進行解密。比較類似非對稱密鑰。
5、 利用密碼短語方式:
搭配EncryptBypassPhrase進行加密,使用DecryptByPassPhrase函數來解密。可以使用有意義的短語或其他數據行,當成加密、解密的關鍵字,比較適合一般的數據加解密。
案例:
1、 Convert方式:
- a) USE tempdb
- b) GO
- c) CREATETABLE d) (
- e) userID INT f) userName VARCHAR g) userSalary FLOAT h) cyberalary NVARCHAR(MAX i) ) ;
- j)
- k) INSERTINTO l) ( userName, userSalary )
- m) VALUES'taici' n) ( 'hailong' o) ( 'meiyuan' p) --ALTER TABLE test q) --ADD userNewSalary VARBINARY(512) r) --使用轉換函數把數據轉換成varbinary,改變編碼方式。 s) SELECT t) CONVERT u) FROM v) --把數據轉換成int,可以恢復原有編碼方式 w) SELECT x) CONVERTINT y) FROM2、對稱密鑰:
- --創建對稱密鑰 b) USE AdventureWorks
- c) GO
- d) CREATEKEY e) WITHBYPASSWORD'P@ssw0rd' f) GO
- g) --注意事項:在啟用時,需要先OPEN SYMMETRIC KEY 搭配密鑰密碼,否則所產生的數據都會是null值。而且需要搭配Key_GUID函數來使用 h) --打開對稱密鑰 i) OPENKEYBYPASSWORD'P@ssw0rd' j) --進行數據加密 k) SELECT'SymKey123'CONVERTVARCHARmax l) FROM m)
- n) --檢查加密后長度,利用datalength()函數 o) SELECT'SymKey123'CONVERTVARCHARMAX p) FROM q) GO
- r) --把加密后數據更新到原來另外的列上 s) UPDATE t) SET'SymKey123'CONVERTVARCHARmax u) --解密:解密過程同樣需要OPEN SYMMETRIC KEY ,且需要利用DECRYPTBYKEY 和CONVERT函數 v) OPENKEYBYPASSWORD'P@ssw0rd' w)
- x) SELECTCONVERTVARCHARMAXCONVERTVARCHARMAX y) FROM3、非對稱密鑰:
- --非對稱密鑰使用兩種不同的密鑰,所以加密是是不需要輸入密碼驗證,但解密時就需要 b) USE AdventureWorks
- c) GO
- d) CREATEKEYWITHBYPASSWORD'P@ssw0rd' e) GO
- f)
- g) --添加新列存儲加密后的數據 h) ALTERTABLEADDMAX i) GO
- j) --進行加密 k) SELECT'AsymKey123'CONVERTVARCHARMAX l) FROM m) GO
- n)
- o) --把數據更新到一個新列 p) UPDATE q) SET'AsymKey123'CONVERTVARCHARMAX r)
- s)
- t) SELECT--addressline3 u) FROM v)
- w) --解密:此過程一定要使用密碼來解密,此處的類型要與加密時相同,比如加密時用varchar,而這里用nvarchar的話是解密不了的。 x) SELECTTOPCONVERTVARCHARMAXCONVERTVARCHARMAX'AsymKey123''P@ssw0rd'AS y) FROM4、證書加密:
- --證書加密:首先建立證書(certificate) b) CREATE--證書名 c) ENCRYPTION BYPASSWORD'P@ssw0rd'--密碼 d) WITH'Address Certificate'--證書描述 e) START_DATE='2012/06/18'--證書生效日期 f) EXPIRY_DATE='2013/06/18'--證書到期日 g) GO
- h) --利用證書加密 i) SELECT'certKey123'CONVERTVARCHARMAX j) FROM k)
- l) --添加新列存放加密數據 m) ALTERTABLEADDMAX n)
- o) --把加密后數據放到新列 p) UPDATE q) SET'certKey123'CONVERTVARCHARMAX r)
- s) --解密 t) SELECTCONVERTVARCHARMAXCONVERTVARCHARMAX'certKey123''P@ssw0rd' u) FROM5、短語加密:
- --短語加密:該過程較為簡單,只需要使用EncryptByPassPhrase函數,使用短語加密時,參考的數據航不可以變動,否則解密失敗。 b) SELECT'P@ssw0rd'CONVERT c) FROM d)
- e) --添加新列存放數據,注意,ENCRYPTBYPASSPHRASE函數返回的是VARBINARY類型 f) ALTERTABLEADD g)
- h) --將數據更新,過程中使用P@ssw0rd和AddressID數據行當成密碼短語 i)
- j) UPDATE k) SET'P@ssw0rd'CONVERT l)
- m) SELECTFROM問題二:如何保護數據庫對象定義,避免發生過渡暴露敏感信息?
一般的保護措施是在創建對象時使用WITH ENCRYPTION來把對象加密,這樣就無法查看定義。但是問題是對於維護來說就成了問題,而且備份還原時這部分對象是會丟失的。
其中一個解決方法是把定義語句放到對象的【擴展屬性】中保存,這樣能解決上面的問題。
下面舉個例子 copy
- --1、建立已加密的存儲過程
- USE AdventureWorks
- GO
- CREATE PROC test
- WITH ENCRYPTION
- AS
- SELECT SUSER_SNAME() ,
- USER_NAME()
- GO
- --2、將上述定義內容去除,利用短語加密搭配EncryptByPassPhrase函數加密,然后在用sys.sp_addextendedproperty存儲過程,指定一個擴展名稱。
- USE AdventureWorks
- GO
- DECLARE @sql VARCHAR(MAX)
- SET @sql = 'CREATE PROC Test WITH ENCRYPTION AS SELECT suer_sname(),user_name() GO'
- --3、將內容加密后轉換成sql_variant數據類型
- DECLARE @bsql SQL_VARIANT
- SET @bsql = ( SELECT CONVERT(SQL_VARIANT, ENCRYPTBYPASSPHRASE('P@ssw0rd',
- CONVERT(VARCHAR(MAX), @sql)))
- )
- --4、新增到指定存儲過程的擴展屬性中:
- EXEC sys.sp_addextendedproperty @name = N'test定義', @value = N'System.Byte[]',
- @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'PROCEDURE',
- @level1name = N'test'
- GO
- EXEC sys.sp_addextendedproperty @name = N'代碼內容',
- @value = N'CREATE PROC Test WITH ENCRYPTION AS SELECT suer_sname(),user_name() GO',
- @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'PROCEDURE',
- @level1name = N'test'
- GO
- --5、還原
- DECLARE @pwd VARCHAR(100)= 'P@ssw0rd'
- --密碼短語
- DECLARE @proc VARCHAR(100)= 'test'
- --存儲過程名
- DECLARE @exName NVARCHAR(100)= '代碼內容'
- --擴充屬性名
- --將原本結果查詢
- SELECT value
- FROM sys.all_objects AS sp
- INNER JOIN sys.extended_properties AS P ON P.major_id = sp.object_id
- AND P.minor_id = 0
- AND P.class = 1
- WHERE ( P.name = @exName )
- AND ( ( sp.type = N'p'
- OR sp.type = N'rf'
- OR sp.type = 'pc'
- )
- AND ( sp.name = @proc
- AND SCHEMA_NAME(sp.schema_id) = N'dbo'
- )
- )

