在《SQL Server 非對稱秘鑰在資料加密中的應用》一文中,我們了解到可以使用非對稱秘鑰進行資料加密。本文帶着大家深入了解非對稱秘鑰的生命周期,包括建立、修改和删除。
為了熟悉非對稱秘鑰,我們先建立一個資料庫作為測試環境:
CREATE DATABASE AsymmetricKeyAdmin ON PRIMARY
(NAME='AsymmetricKeyAdmin',FILENAME='D:\database\AsymmetricKeyAdmin.mdf')
LOG ON
(NAME='AsymmetricKeyAdmin_log',FILENAME='D:\database\AsymmetricKeyAdmin_log.ldf')
建立非對稱秘鑰
非對稱秘鑰的建立有五種方式,分别為:
- 密碼加密私鑰的非對稱秘鑰
- DMK加密私鑰的非對稱秘鑰
- 從強命名加密的dll檔案中建立
- 從檔案中建立
- 從EKM中建立
密碼加密私鑰的非對稱秘鑰建立
USE AsymmetricKeyAdmin
GO
--建立密碼加密的非對稱密鑰
CREATE ASYMMETRIC KEY AsyEncryptByPWD
WITH ALGORITHM=RSA_2048
ENCRYPTION BY PASSWORD='[J,XJK8|AwE*rLk'

從動态視圖sys.asymmetric_keys 我們可以清楚的看到,該非對稱密鑰是使用密碼加密的,同時我們可以看到,在這裡有個公鑰字段public_key,這個是對稱密鑰所沒有的。
DMK加密私鑰的非對稱秘鑰
--建立資料庫主密鑰
CREATE MASTER KEY ENCRYPTION BY PASSWORD='[J,XJK8|AwE*rLk'
--建立資料庫主密鑰加密的非對稱密鑰
CREATE ASYMMETRIC KEY AsyEncrptyByDMK
WITH ALGORITHM=RSA_2048
非對稱秘鑰算法的選擇,可參考《SQL Server 非對稱秘鑰加密算法RSA》。
從強名稱加密的dll中建立非對稱秘鑰
--從強名稱加密的dll中建立非對稱密鑰
CREATE ASYMMETRIC KEY AsyKeyFromDll
FROM EXECUTABLE FILE='E:\AsmDll\UDF_CLR.dll'
從強名稱加密的dll中建立的非對稱秘鑰是沒有私鑰的,公鑰是存在的。
注意:dll的強名稱加密過程可以參考《解決因SQL Server資料庫引用程式集而不得不開啟trustworthy方法》文章中的描述。
使用程式集建立非對稱秘鑰
這裡我們仍然使用上文中使用的UDF_CLR.dll,不過是使用它先建立程式集,然後再用該程式集建立非對稱秘鑰。
--不開啟用trustworthy 時,建立程式集方案:
USE master --這個資料庫一定是master
GO
--建立非對稱密鑰
CREATE ASYMMETRIC KEY SQLCLRTestKey FROM EXECUTABLE FILE = 'E:\AsmDll\UDF_CLR.dll'
--建立登入名
CREATE LOGIN SQLCLRTestLogin FROM ASYMMETRIC KEY SQLCLRTestKey
--把權限授予給該登入名
GRANT EXTERNAL ACCESS ASSEMBLY TO SQLCLRTestLogin;
USE AsymmetricKeyAdmin
GO
--建立程式集
CREATE ASSEMBLY UDF FROM
'E:\AsmDll\UDF_CLR.dll'
WITH PERMISSION_SET=EXTERNAL_ACCESS;
--使用程式集建立非對稱密鑰
CREATE ASYMMETRIC KEY AsyKeyFromAssembly
FROM ASSEMBLY UDF
此時會報如下錯誤:
因為我們上文使用UDF_CLR.dll 建立了非對稱秘鑰,即使用同一個dll建立非對稱秘鑰,無論是直接使用dll檔案建立,還是間接的使用程式集建立,這兩個非對稱秘鑰是相同的,是以會報非對稱秘鑰已經存在的錯誤。
接下來我們先删除上文建立的非對稱秘鑰 AsyKeyFromDll :
USE AsymmetricKeyAdmin
GO
--先删除非對稱秘鑰AsyKeyFromDll
DROP ASYMMETRIC KEY AsyKeyFromDll
再執行如下建立非對稱秘鑰的腳本:
--使用程式集建立非對稱密鑰
CREATE ASYMMETRIC KEY AsyKeyFromAssembly
FROM ASSEMBLY UDF
建立成功,檢查動态視圖:
仍然沒有私鑰存在。
使用強名稱加密的私鑰檔案建立非對稱秘鑰
--使用文建立非對稱密鑰
CREATE ASYMMETRIC KEY AsyKeyFromFile
FROM FILE='E:\AsmDll\pri.snk'
--删除從程式集中建立的非對稱密鑰AsyKeyFromAssembly
DROP ASYMMETRIC KEY AsyKeyFromAssembly
再次執行使用檔案建立非對稱秘鑰的腳本,建立成功。我們檢視動态視圖:
和從dll建立非對稱秘鑰、從程式集中建立非對稱秘鑰不同的是,從檔案中建立的非對稱秘鑰是使用資料庫主秘鑰進行加密的(因為本文前面建立資料庫主秘鑰加密的非對稱秘鑰中已經建立了DMK,否則在從檔案中建立非對稱秘鑰之前需要先建立DMK)。
使用EKM建立非對稱秘鑰
在使用EKM時,我們首先需要啟用EKM provider,腳本如下:
-- 啟動進階配置
sp_configure 'show advanced options', 1 ;
GO
RECONFIGURE ;
GO
-- 啟動EKM provider
sp_configure 'EKM provider enabled', 1 ;
GO
RECONFIGURE ;
GO
假設第三加密提供程式存儲在E:\AsmDll路徑下,檔案名為UDF_CLR.dll,先建立 CRYPTOGRAPHIC PROVIDER
CREATE CRYPTOGRAPHIC PROVIDER EKM_Prov
FROM FILE = 'E:\CertExeFile\UDF_CLR.dll' ;
GO
使用EKM建立非對稱秘鑰:
--使用EKM建立非對稱密鑰
CREATE ASYMMETRIC KEY AsyKey
FROM PROVIDER EKM_Prov
WITH
PROVIDER_KEY_NAME='KeyForSensitiveData',
CREATION_DISPOSITION=OPEN_EXISTING;
GO
修改非對稱秘鑰
修改私鑰加密密碼:
ALTER ASYMMETRIC KEY AsyEncryptByPWD
WITH PRIVATE KEY (
DECRYPTION BY PASSWORD='[J,XJK8|AwE*rLk'
,ENCRYPTION BY PASSWORD ='0faalc23(gI0r;>'
)
将密碼加密非對稱秘鑰私鑰更改為DMK加密非對稱秘鑰私鑰
OPEN MASTER KEY DECRYPTION BY PASSWORD = '[J,XJK8|AwE*rLk';
ALTER ASYMMETRIC KEY AsyEncryptByPWD WITH PRIVATE KEY (
DECRYPTION BY PASSWORD = '[J,XJK8|AwE*rLk' );
CLOSE MASTER KEY
注意:
- 資料庫必須已經存在資料庫主秘鑰,否則需要先建立DMK
- 更改前需要先打開資料庫主秘鑰
可以使用如下方式将DMK加密非對稱秘鑰私鑰更改為密碼加密:
ALTER ASYMMETRIC KEY AsyEncryptByPWD WITH PRIVATE KEY(
ENCRYPTION BY PASSWORD ='[J,XJK8|AwE*rLk')
SELECT * FROM sys.asymmetric_keys
移除非對稱秘鑰私鑰
ALTER ASYMMETRIC KEY AsyEncryptByPWD
REMOVE PRIVATE KEY
值得注意的是,私鑰一旦移除,就不能使用ALTER ASYMMETRIC KEY 添加了:
同樣我們也不能為上文中使用dll或程式集建立的非對稱秘鑰添加私鑰。
沒有私鑰,也就沒有辦法解密了,這和我們後面将會提到的永久加密有些異曲同工的效果。