在《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或程序集创建的非对称秘钥添加私钥。
没有私钥,也就没有办法解密了,这和我们后面将会提到的永久加密有些异曲同工的效果。