加密是一种使用密钥和证书的算法来混淆数据的过程。如果没有密钥和证书,即使得到了数据,也无法得知数据的本来面貌,数据就没有价值了。但是由于加解密本身就是一种非常耗资源(特别是CPU跟I/O )的计算操作,同时加密后的数据本质上会增大,所以也往往会带来性能的下降。所以一般都只能按需使用。
SQL Server到2016为止,加入了很多种加密技术,比如TDE、cell-level加密和始终加密,下面来介绍一下加密的概念。为后续讲解做铺垫。
Defense-in-Depth ,是一种横跨整个IT范围的技术,本质就是多层防御。比如企业会有外围网络防火墙,内网防火墙等。在SQL Server层,通常使用加密技术来实现这种访问控制策略。换句话来说,加密通过增加额外的防御层来实现提高纵深防御能力。
Symmetric Keys,虽然是“钥匙”,但是本质就是加密数据的算法。并且是加密中最弱的算法,因为使用相同的算法来加解密数据。不过即使是最弱的算法,也能增加纵深防御的能力,毕竟不是每个攻击者都是顶级的。对于对称密钥,可以使用密码或者另一个密钥甚至一个证书来加密。
Asymmetric Keys,跟对称密钥相对,它使用一对密钥(算法),一个加密一个解密,加密的密钥称为私钥(private key),解密的密钥称为公钥(public key)。
Certificates,证书由受信任的源 (称为证书颁发机构 (CA)) 颁发。使用的是非对称密钥,但是也提供将公钥绑定到主体或设备 (其中包含相应私钥) 的数字签名语句。
Self-Signed Certificate,自签名证书是由其身份证明相同的实体签署的证书。可以由 SQL Server 创建。
Windows Data Protection API ( DPAPI) ,是与 Windows 操作系统一起运行的加密应用程序编程接口 (API)。可以使用用户安全信息或者域安全信息来加密密钥。DPAPI用于加密服务主密钥(service master key),服务主密钥在SQL Server中是高层加密,下面将介绍一下SQL Server加密概念。
SQL Server加密功能依赖于密钥和证书的层次结构。层面的根是服务主密钥(service master key),接下来介绍一下主密钥(master key)和EKM(Extensible Key Management)及SQL Server的加密层级。
master keys,服务主密钥在实例安装后自动创建,用于加密数据库主密钥、凭证(credentials)和使用DPAPI的链接服务器的密钥。在每个实例中有且仅有一个服务主密钥,从SQL 2012开始,服务主密钥是由AES 256算法产生的一个对称密钥,在此之前使用Triple DES算法产生。因此如果从2008R2或者更低级的版本升级实例,最好重新生成密钥。但是这会导致现有的加密层次结构解密并重新加密。也就是说所有由主密钥加密的密钥和证书需要解密和重新加密。这个操作非常耗时。
对于重新产生服务主密钥,可以使用下面语句来实现。如果某些操作失败,可以使用FORCE关键字强制错误后继续运行:
ALTER SERVICE MASTER KEY REGENERATE ;
由于这个密钥极其重要,所以在创建或者重建后必须进行备份。并且保存在安全的地方,用于灾难恢复,也可以用来迁移实例时避免加密相关的问题。备份还原服务主密钥可以使用下面脚本:
--备份服务主密钥
BACKUP SERVICE MASTER KEY
TO FILE = 'c:\keys\service_master_key'
ENCRYPTION BY PASSWORD = 'Pa$$w0rd' ;
--还原服务主密钥
RESTORE SERVICE MASTER KEY
FROM FILE = 'c:\keys\service_master_key'
DECRYPTION BY PASSWORD = 'Pa$$ w0rd ' ;
注意上面c:\keys\后面的service_master_key是密钥文件不是目录。并且没有后缀名。
数据库主密钥也是一个对称密钥,由AES 256算法加密。服务主密钥用来加密私钥和证书并存储在某个数据库中。数据库主密钥使用密码来加密,但是会创建一个副本,使用服务主密钥加密,这样使得在需要时可以自动打开服务主密钥,如果副本不存在,则要手动打开。如果副本不存在或已损坏, 则需要显式打开密钥, 以便您使用层次结构 (使用服务主密钥加密的密钥)下面的密钥。服务主密钥的副本存储在数据库和主数据库中。
所以在备份服务主密钥的同时,也不要忘记备份数据库主密钥,因为密钥丢失意味着数据丢失。极端情况下可能全库不可用。下面来演示一下对AdventureWorks2016数据库创建一个数据库主密钥,然后备份及还原。跟服务主密钥一样,可以使用FORCE关键字来强制在失败后继续,但是有丢失数据的风险。
USE AdventureWorks2016
GO
--创建数据库主密钥,使用密码加密
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Pa$$w0rd' ;
--备份密钥到C盘keys文件夹,备份需要提供密码
BACKUP MASTER KEY TO FILE = 'c:\keys\DB_master_key'
ENCRYPTION BY PASSWORD = 'Pa$$w0rd';
--还原密钥,需要提供密码才能还原(进行解密操作),然后再用这个密钥(带有密码)在库内加密
RESTORE MASTER KEY
FROM FILE = 'c:\keys\DB_master_key'
DECRYPTION BY PASSWORD = 'Pa$$w0rd'
ENCRYPTION BY PASSWORD = 'Pa$$w0rd'
Extensible Key Management,允许生成和管理用于在第三方硬件安全模块(Hardware Security Module,HSM)中保护SQL Server数据的密钥和证书。EKM使用Microsoft Cryptographic API(MS-CAPI)与SQL Server交互。由于密钥和数据不会一起存储,所以更加安全。当使用HSM时,可以借助第三方工具的基于硬件的加解密,把性能影响降低。
密钥存储,Key Stores提供了一个安全的存储空间和可信任的密钥及证书源。可选的密钥存储有本地的Windows证书存储,Windows Azure中的Azure密钥库或者其他第三方密钥存储供应商。
图片来自于:Encryption Hierarchy