适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
Always Encrypted 和“具有安全 Enclave 的 Always Encrypted”是旨在保护 Azure SQL 数据库、Azure SQL 托管实例和 SQL Server 数据库中的敏感信息(包括信用卡号以及国家或地区标识号,如美国社会安全号码)的功能。 可以在客户端应用程序中加密敏感数据,确保永远不会向数据库引擎公开加密密钥。 此方法在拥有数据并可以查看数据的人员与管理数据但不应具有访问权限的人员(本地数据库管理员、云数据库操作员或其他高特权未经授权的用户)之间提供分隔。 因此,Always Encrypted 允许客户将其敏感数据安全地存储在云中,从而降低数据被恶意内部人员窃取的风险。
Always Encrypted 具有某些限制,例如无法对加密数据执行作,包括排序和筛选(使用确定性加密的点查找除外)。 此限制意味着某些查询和应用程序可能与 Always Encrypted 不兼容,或者可能需要对应用程序逻辑进行重大更改。
为了解决这些限制,“具有安全 Enclave 的 Always Encrypted”使数据库引擎能够在称为“安全 enclave”的受保护内存区域内处理加密数据。 安全 enclave 通过支持模式匹配、各种比较运算符和就地加密增强了 Always Encrypted 的机密计算能力。
Always Encrypted 可确保应用程序无缝加密。 在客户端上,启用 Always Encrypted 的驱动程序先加密敏感数据,然后再将其发送到数据库引擎,并自动重写查询以维护应用程序语义。 它还会自动解密来自加密数据库列的查询结果。
配置 Always Encrypted
注意
对于需要执行模式匹配、对加密列使用比较运算符、排序和索引的应用程序,请使用 安全 enclave 实现 Always Encrypted。
本部分概述了如何设置 Always Encrypted。 有关详细信息和入门指南,请参阅教程:Always Encrypted 入门。
若要在数据库中配置 Always Encrypted,请执行下面的步骤:
预配加密密钥以保护数据。 Always Encrypted 使用两种类型的密钥:
- 列加密密钥。
- 列主密钥。
列加密密钥对加密列中的数据进行加密。 列主密钥是对一个或多个列加密密钥进行加密的密钥保护密钥。
将列主密钥存储在数据库系统外部的受信任密钥存储中,例如 Azure Key Vault、 Windows 证书存储或硬件安全模块。 完成此步骤后,配置列加密密钥,并使用列主密钥加密每个密钥。
最后,请将有关密钥的元数据存储在数据库中。 列主密钥元数据包括列主密钥的位置。 列加密密钥元数据包含列加密密钥的加密值。 数据库引擎不以纯文本形式存储或使用任何密钥。
有关管理 Always Encrypted 密钥的详细信息,请参阅 Always Encrypted 密钥管理概述。
为包含敏感信息的特定数据库列设置加密,以确保保护。 此步骤可能需要使用加密列创建新表或加密现有列和数据。 为列配置加密时,请指定有关加密算法的详细信息、用于保护数据的列加密密钥以及加密类型。 Always Encrypted 支持两种类型的加密:
对于任何给定的纯文本值,“确定性加密”始终生成相同的加密值。 通过使用确定性加密,可以对加密列执行点查找、相等联接、分组和索引编制。 但是,未经授权的用户可能会通过检查加密列中的模式来猜测有关加密值的信息,尤其是在存在一组可能的加密值(如 True/False 或 North/South/East/West 区域)时。
随机加密使用一种不可预测地加密数据的方法。 每个相同的纯文本输入都会产生不同的加密输出。 此方法提高了随机加密的安全性。
若要对加密列进行模式匹配以及使用比较运算符、排序和索引,请采用 Always Encrypted with secure enclaves 功能,并应用随机加密。 Always Encrypted(没有安全 enclave)随机加密不支持对加密列进行搜索、分组、编制索引或联接。 相反,对于用于搜索或分组目的的列,必须使用确定性加密。 此加密类型允许对加密列执行点查找、相等联接、分组和索引等作。
由于数据库系统设计无法访问加密密钥,任何列加密都需要在数据库外部移动和加密数据。 加密过程可能需要很长时间,并且容易受到网络中断。 此外,如果需要稍后重新加密列(例如轮换加密密钥或更改加密类型时),则再次遇到相同的困难。 使用“具有安全 Enclave 的 Always Encrypted”消除了将数据移出数据库的必要性。 由于 enclave 受信任,因此应用程序内的客户端驱动程序或 SQL Server Management Studio(SSMS)等工具可以在加密作期间安全地与 enclave 共享密钥。 然后,enclave 可以就地加密或重新加密列,从而显著减少这些操作所需的时间。
有关 Always Encrypted 加密算法的详细信息,请参阅 Always Encrypted 加密。
可以使用 SQL 工具执行上述步骤:
- 使用 SQL Server Management Studio 预配 Always Encrypted 密钥
- 使用 PowerShell 配置“始终加密”功能
- sqlpackage - 自动执行安装过程
为了确保始终加密密钥和受保护的敏感数据永远不会以纯文本形式向数据库环境显示,数据库引擎不能参与密钥预配和数据加密或解密作。 因此,Transact-SQL (T-SQL) 不支持密钥预配或加密操作。 由于同样原因,加密现有数据或重新加密它(使用不同的加密类型或列加密密钥)需要在数据库外部执行(SQL 工具可以自动执行)。
更改加密列的定义之后,需执行 sp_refresh_parameter_encryption,以更新该对象的 Always Encrypted 元数据。
限制
对加密列的查询存在以下限制:
不能对使用随机加密加密的列执行计算。 确定性加密支持以下涉及相等比较的操作。 不允许执行其他操作
注意
对于需要执行模式匹配、使用比较运算符、排序和索引于加密列的应用程序,请使用具有安全隔离区的 Always Encrypted。
不能使用触发涉及纯文本和加密数据的计算的查询语句。 例如:
- 将加密列与纯文本列或文本进行比较。
- 将数据从纯文本列复制到加密列(或反之亦然)
UPDATE、BULK INSERT、SELECT INTO、或INSERT..SELECT。 - 将文本插入加密列。
此类语句会导致操作数冲突错误,如下所示:
Msg 206, Level 16, State 2, Line 89 Operand type clash: char(11) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_1', column_encryption_key_database_name = 'ssn') collation_name = 'Latin1_General_BIN2' is incompatible with char应用程序需要使用查询参数来为加密列提供值。 例如,将数据插入加密列或使用确定性加密筛选数据时,请使用查询参数。 不支持传递对应于加密列的文本或 T-SQL 变量。 有关特定于使用的客户端驱动程序的详细信息,请参阅使用 Always Encrypted 开发应用程序。
在 SSMS 中,必须对 Always Encrypted 变量应用参数化来执行处理与加密列关联的值的查询。 此要求包括将数据插入加密列或对其应用筛选器等方案(如果使用确定性加密)。
不支持针对加密列的表值参数。
不支持使用以下子句的查询:
对于具有以下特征的列,不支持 Always Encrypted:
- 使用以下数据类型之一的列: xml、 timestamp、 rowversion、 image、 ntext、 text、 sql_variant、 hierarchyid、 geography、 geometry、 vector、alias、user-defined 类型。
- FILESTREAM 列。
- 具有 IDENTITY 属性的列。
- 具有 ROWGUIDCOL 属性的列。
- 除二进制代码点 () 排序规则以外的排序规则的字符串(
_BIN2、char 和其他)列。 排序规则不得与数据库的默认排序规则不同。 - 使用随机加密时用作聚集索引和非聚集索引的键的列(支持使用确定性加密在列上添加索引)。
- 全文检索中包含的列(Always Encrypted 不支持全文搜索)。
- 指定表中的计算列。
- 当表达式执行不受 Always Encrypted 支持的操作时,计算列所引用的列。
- 使用稀疏列。
- 使用随机加密时统计信息引用的列(支持确定性加密)。
- 分区列。
- 包含默认约束的列。
- 使用随机加密时 unique 约束引用的列(支持确定性加密)。
- 使用随机加密时的主键列(支持确定性加密)。
- 使用随机加密或确定性加密时引用外键约束中的列(如果被引用和引用列使用不同的键或算法)。
-
check 约束引用的列。
- 使用更改数据捕获来捕获或跟踪的列。
- 具有更改跟踪的表中的主键列。
- 使用 动态数据掩码屏蔽的列。
- 在本机编译的模块中引用内存优化表中的列时,加密不能应用于该表中的任何列。
- 延伸数据库表中的列。 (无法为延伸启用其列已使用始终加密加密的表。)
重要
SQL Server 2022 (16.x) 和 Azure SQL 数据库中已弃用 Stretch Database。 在数据库引擎的未来版本中将删除此功能。 请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。
- 外部 (PolyBase) 表中的列(注意:支持在同一查询中使用外部表和列已加密的表)。
以下功能对加密的列不起作用:
- SQL Server 复制(事务性复制、合并复制或快照复制)。 支持物理复制功能,包括 AlwaysOn 可用性组。
- 分布式查询(链接服务器、OPENROWSET (Transact-SQL)、OPENDATASOURCE (T-SQL))。
- 对从不同数据库加密的列执行联接的跨数据库查询。
Always Encrypted Transact-SQL 参考
Always Encrypted 使用以下 Transact-SQL 语句、系统目录视图、系统存储过程和权限。
语句
| DDL 语句 | Description |
|---|---|
| 创建列主密钥 | 在数据库中创建列主密钥元数据对象 |
| 删除列主密钥 | 删除数据库中的列主密钥。 |
| 创建列加密密钥 | 创建列加密密钥元数据对象。 |
| 修改列加密密钥 | 在数据库中更改列加密密钥,添加或删除加密的值。 |
| DROP COLUMN ENCRYPTION KEY(删除列加密密钥) | 删除数据库中的列加密密钥。 |
| CREATE TABLE (使用加密方式) | 指定加密列 |
系统目录视图和存储过程
| 系统目录视图和存储过程 | Description |
|---|---|
| sys.column_encryption_keys | 返回有关列加密密钥的信息 (CEK) |
| sys.column_encryption_key_values | 返回有关列加密密钥 (CEK) 的加密值的信息 |
| sys.column_master_keys | 为每个数据库主密钥返回一行 |
| sp_refresh_parameter_encryption | 更新指定的非绑定到架构的存储过程、用户定义函数、视图、DML 触发器、数据库级 DDL 触发器或服务器级 DDL 触发器的参数的 Always Encrypted 元数据。 |
| sp_describe_parameter_encryption | 分析指定的 Transact-SQL 语句及其参数,以确定哪些参数对应于使用 Always Encrypted 功能保护的数据库列。 |
有关为每个列存储的加密元数据的信息,请参阅 sys.columns。
数据库权限
Always Encrypted 使用四个数据库权限。
| 系统目录视图和存储过程 | Description |
|---|---|
ALTER ANY COLUMN MASTER KEY |
创建和删除列主密钥元数据时需要。 |
ALTER ANY COLUMN ENCRYPTION KEY |
创建和删除列加密密钥元数据时需要。 |
VIEW ANY COLUMN MASTER KEY DEFINITION |
在访问和读取列主密钥元数据(查询加密列所需)时需要。 |
VIEW ANY COLUMN ENCRYPTION KEY DEFINITION |
在访问和读取列加密密钥元数据(查询加密列所需)时需要。 |
下表总结了常见的操作所需的权限。
| 场景 | ALTER ANY COLUMN MASTER KEY |
ALTER ANY COLUMN ENCRYPTION KEY |
VIEW ANY COLUMN MASTER KEY DEFINITION |
VIEW ANY COLUMN ENCRYPTION KEY DEFINITION |
|---|---|---|---|---|
| 密钥管理(在数据库中创建、更改或查看密钥元数据) | X | X | X | X |
| 查询加密列 | X | X |
重要注意事项
选择加密列时,需要
VIEW ANY COLUMN MASTER KEY DEFINITION和VIEW ANY COLUMN ENCRYPTION KEY DEFINITION权限。 即使用户无权访问其密钥存储中的列主密钥,这些权限也会保护列,并且会阻止访问纯文本。在 SQL Server 中, 公共 固定数据库角色默认授予
VIEW ANY COLUMN MASTER KEY DEFINITION和VIEW ANY COLUMN ENCRYPTION KEY DEFINITION权限。 数据库管理员可以选择撤销或拒绝这些 对公共 角色的权限,并将其授予特定角色或用户以实现更受限的控制。在 SQL 数据库中, 公共 固定数据库角色默认不授予
VIEW ANY COLUMN MASTER KEY DEFINITION和VIEW ANY COLUMN ENCRYPTION KEY DEFINITION权限。 此更改使某些使用旧版 DacFx 的现有旧工具能够正常工作。 若要使用加密列(即使未解密它们),数据库管理员必须显式授予VIEW ANY COLUMN MASTER KEY DEFINITION和VIEW ANY COLUMN ENCRYPTION KEY DEFINITION权限。