适用于: SQL Server 2019 (15.x) 及更高版本 - 仅限 Windows 
Azure SQL 数据库
通过启用就地加密和更丰富的机密查询,具有安全 enclave 的 Always Encrypted 扩展了 Always Encrypted 的机密计算功能。 SQL Server 2019 (15.x) 及更高版本以及 Azure SQL 数据库中提供了具有安全 enclave 的 Always Encrypted。
Azure SQL 数据库(2015 年)和 SQL Server 2016 (13.x) 中引入的 Always Encrypted 可保护敏感数据的机密性免受恶意软件以及以下具有较高特权但未经授权的用户的攻击:数据库管理员 (DBA)、计算机管理员、云管理员,或可以合法访问服务器实例和硬件等但不应有权访问部分或全部实际数据的任何其他人。
如果没有本文中所讨论的增强功能,Always Encrypted 会通过在客户端加密数据并且从不允许数据或相应的加密密钥以纯文本形式显示在 SQL Server 引擎中来保护数据。 因此,数据库内的加密列上的功能受到严格限制。 可以对加密数据执行的唯一操作是相等比较(仅适用于确定性加密)。 数据库内不支持所有其他操作,包括加密操作(初始数据加密或密钥轮换)和更丰富的查询(例如模式匹配)。 用户需要将数据移出数据库才能对客户端执行这些操作。
使用具有安全 enclave 的 Always Encrypted,可以在服务器端对安全 enclave 内的纯文本数据进行某些计算,从而解决这些限制。 安全 Enclave 是数据库引擎过程中受保护的内存区域。 安全 Enclave 对托管计算机上的数据库引擎的其余部分和其他进程显示为不透明盒。 无法从外部查看 enclave 内的任何数据或代码,即使采用调试程序也是如此。 这些属性使安全 enclave 成为受信任的执行环境,该执行环境可安全访问明文中的加密密钥和敏感数据,而不会破坏数据的保密性。
Always Encrypted 使用安全 enclave,如下图中所示:
 
在分析应用程序提交的 Transact-SQL 语句时,数据库引擎会确定语句是否包含对需要使用安全 Enclave 的加密数据执行的任何操作。 对于此类语句:
- 客户端驱动程序向安全 enclave 发送操作所需的列加密密钥(通过安全通道),并提交要执行的语句。 
- 处理该语句时,数据库引擎将加密列上的加密操作或计算委托给安全 Enclave。 如果需要,enclave 将对数据进行解密,并在纯文本上执行计算。 
在语句处理期间,不会在数据库引擎中以纯文本形式公开安全 Enclave 之外的数据或列加密密钥。
受支持的客户端驱动程序
若要使用具有安全 enclave 的 Always Encrypted,应用程序必须使用支持该功能的客户端驱动程序。 配置应用程序和客户端驱动程序以启用 enclave 计算和 enclave 证明(请参阅下方的安全 enclave 证明 部分)。 有关详细信息(包括受支持的客户端驱动程序的列表),请参阅使用 Always Encrypted 开发应用程序。
受支持的 enclave 技术
Always Encrypted 支持以下 enclave 技术(或 enclave 类型):
- 基于虚拟化的安全性 (VBS) enclave(也称为虚拟安全模式,或 VSM enclave)是一种基于软件的技术,依赖于 Windows 虚拟机监控程序,不需要任何特殊硬件。
- Intel Software Guard Extensions (Intel SGX) enclave 是一种基于硬件的受信任执行环境技术。
数据库可用的 enclave 类型取决于托管该数据库的 SQL 产品(Azure SQL 数据库与SQL Server)和(如果使用的是 Azure SQL 数据库)数据库配置情况。
- 在 SQL Server 2019 (15.x) 及更高版本中,Always Encrypted 支持 VBS enclave。 (不支持 Intel SGX enclave。) 
- 在 Azure SQL 数据库中,数据库可以使用 Intel SGX enclave 或 VBS enclave,具体取决于数据库配置为运行的硬件: - 使用 DC 系列硬件配置(可通过 vCore 购买模型获得)的数据库使用 Intel SGX enclave。
- 除采用 vCore 购买模型的 DC 系列和使用 DTU 购买模型的数据库以外,使用其他配置的数据库都可以配置为使用 VBS enclave。
 - 注意 - VBS enclave 目前在除 Jio 印度中部之外的所有 Azure SQL 数据库区域中都可用。 
有关每个 enclave 类型提供的级别保护的重要信息,请参阅安全注意事项部分。
安全 enclave 证明
enclave 证明是一种深层防御机制,可帮助检测涉及恶意管理员篡改 enclave 代码或其环境的攻击。
enclave 证明允许客户端应用程序与数据库的安全 enclave 建立信任,应用程序需在应用使用 enclave 处理敏感数据之前连接到该数据库。 证明工作流可验证 enclave 是正版 VBS 或 Intel SGX enclave,并且其中运行的代码是 Always Encrypted 的真正的 Microsoft 签名的 enclave 库。 在证明期间,应用程序和数据库引擎中的客户端驱动程序都使用客户端指定的终结点与外部证明服务通信。
Always Encrypted 可以使用以下两个证明服务的其中之一:
- Microsoft Azure 证明 - 基于云的证明解决方案。
- 实现 Windows Defender System Guard 运行时证明的主机保护者服务 (HGS)。
若要为应用程序启用具有安全 enclave 的 Always Encrypted,你需要在应用程序中客户端驱动程序的配置中设置证明协议。 证明协议值确定 1) 客户端应用是否将使用证明,如果是,则 2) 证明协议值需指定要使用的证明服务的类型。 下表捕获有效 SQL 产品和 enclave 类型组合支持的证明协议:
| 托管产品 | Enclave 类型 | 支持的证明协议 | 
|---|---|---|
| SQL Server 2019 (15.x) 及更高版本 | VBS enclave | HGS,无证明 | 
| Azure SQL Database | SGX enclave(DC 系列数据库) | Microsoft Azure 证明 | 
| Azure SQL Database | VBS enclave | 无证明 | 
要标注的几个要点:
- 在 SQL Server 2019 (15.x) 及更高版本中,证明 VBS enclave 需要使用 HGS。 你也可以在没有证明的情况下使用 VBS enclave(需要最新的客户端驱动程序)。
- 对于 Azure SQL 数据库中的 Intel SGX enclave(在 DC 系列数据库中),证明是强制操作,它需要 Microsoft Azure 证明。
- Azure SQL 数据库中的 VBS enclave 不支持证明。
有关详细信息,请参阅:
术语
已启用 enclave 的密钥
具有安全 enclave 的 Always Encrypted 引入了已启用 enclave 的密钥的概念:
- 已启用 enclave 的列主密钥 - 具有数据库内的列主密钥元数据对象中指定的 master属性的列ENCLAVE_COMPUTATIONS密钥。 列master密钥元数据对象还必须包含元数据属性的有效签名。 有关详细信息,请参阅 CREATE COLUMN MASTER KEY (Transact-SQL)
- 已启用 enclave 的列加密密钥 – 使用已启用 enclave 的列 master密钥加密的列加密密钥。 只有已启用 enclave 的列加密密钥才能用于安全 enclave 中的计算。
有关详细信息,请参阅管理具有安全 Enclave 的 Always Encrypted 的密钥。
已启用 enclave 的列
已启用 enclave 的列是使用已启用 enclave 的列加密密钥加密的数据库列。
已启用 enclave 的列的机密计算功能
具有安全 enclave 的 Always Encrypted 的两个主要优点是就地加密和丰富的机密查询。
就地加密
借助就地加密,可以对安全 enclave 中的数据库列进行加密操作,而无需将数据移出数据库。 就地加密提高了加密操作的性能和可靠性。 可以使用 ALTER TABLE (Transact-SQL) 语句执行就地加密。
就地支持的加密操作包括:
- 使用已启用 enclave 的列加密密钥加密纯文本列。
- 将已加密的已启用 enclave 的列重新加密为:- 轮换列加密密钥 - 使用新的已启用 enclave 的列加密密钥重新加密列。
- 更改已启用 enclave 的列的加密类型,例如从确定性改为随机。
 
- 解密已启用 enclave 的列中存储的数据(将该列转换为纯文本列)。
只要加密操作中涉及的列加密密钥已启用 enclave,就允许确定性加密和随机加密进行就地加密。
机密查询
注意
SQL Server 2022 (16.x) 添加了对加密列上使用 JOIN、GROUP BY 和 ORDER BY 操作的机密查询的额外支持。
机密查询是 DML 查询,涉及在安全 enclave 内执行的已启用 enclave 的列上的操作。
安全 enclave 内支持的操作包括:
| Operation | Azure SQL Database | SQL Server 2022 (16.x) | SQL Server 2019 (15.x) | 
|---|---|---|---|
| 比较运算符 | 支持 | 支持 | 支持 | 
| BETWEEN (Transact-SQL) | 支持 | 支持 | 支持 | 
| IN (Transact-SQL) | 支持 | 支持 | 支持 | 
| LIKE (Transact-SQL) | 支持 | 支持 | 支持 | 
| DISTINCT | 支持 | 支持 | 支持 | 
| 联接 | 支持 | 支持 | 仅支持嵌套循环联接 | 
| SELECT - ORDER BY 子句 (Transact-SQL) | 支持 | 支持 | 不支持 | 
| SELECT - GROUP BY- Transact-SQL | 支持 | 支持 | 不支持 | 
注意
安全 enclave 中的上述操作需要随机加密。 确定性加密不受支持。 使用确定性加密的列仍可进行相等比较操作。
应将数据库的兼容性级别设置为 SQL Server 2022 (160) 或更高级别。
在 Azure SQL 数据库和 SQL Server 2022 (16.x) 中,对字符串列使用 enclave 的机密查询(char、nchar)要求该列使用二进制码位 (_BIN2) 排序规则或 UTF-8 排序规则。 在 SQL Server 2019 (15.x) 中,需要 a_BIN2 排序规则。
有关详细信息,请参阅使用安全 enclave运行 Transact-SQL 语句。
已启用 enclave 的列上的索引
可以在使用随机加密在已启用 enclave 的列上创建非聚集索引,以加快使用安全 enclave 的机密 DML 查询的运行速度。
为了确保使用随机加密进行加密的列上的索引不会泄露敏感数据,索引数据结构(B 树)中的键值会根据纯文本值进行加密和排序。 按纯文本值进行排序还有助于处理 enclave 中的查询。 当数据库引擎中的查询执行器使用加密列上的索引在 Enclave 内进行计算时,它会搜索索引以查找存储在列中的特定值。 每个搜索都可能涉及多个比较。 查询执行器将所有比较都委托给 enclave,它解密列中存储的值以及要比较的加密索引键值,以纯文本形式执行比较,并向执行器返回比较结果。
仍不支持在使用随机加密但未启用 enclave 的列上创建索引。
使用确定性加密的列上的索引是根据已加密文本(而不是纯文本)进行排序,无论列是否已启用 enclave。
有关详细信息,请参阅对使用具有安全 enclave 的 Always Encrypted 的列创建和使用索引。 有关数据库引擎中索引工作原理的一般信息,请参阅文章描述的群集和非群集索引。
数据库恢复
如果 SQL Server 实例出现故障,它的数据库可能处于以下状态:数据文件可能包含来自未完成事务的一些修改。 启动后,此实例运行数据库恢复过程,其中涉及回滚在事务日志中找到的所有未完成事务,以确保维护数据库完整性。 如果未完成事务对索引进行了任何更改,也需要撤消这些更改。 例如,可能需要删除或重新插入索引中的一些键值。
重要说明
Microsoft 强烈建议,先为数据库启用加速数据库恢复 (ADR),再在使用随机加密进行加密且已启用 enclave 的列上创建首个索引。 默认情况下,ADR 在 Azure SQL 数据库和 Azure SQL 托管实例中启用。 ADR 在 SQL Server 2019(15.x)及更高版本中是可用的,但默认未启用。
使用 传统数据库恢复过程(遵循 ARIES 恢复模式),若要撤消对索引的更改,数据库引擎需要等待,直到应用程序向 enclave 提供列的列加密密钥,这可能需要很长时间。 加速数据库恢复 (ADR) 大大减少了因无法从 enclave 内的缓存获取列加密密钥而必须延迟的撤消操作数。 通过将新的事务被阻止的可能性降到最低,从而大幅提升数据库可用性。 启用 ADR 后,数据库引擎可能仍然需要列加密密钥来完成旧数据版本的清理,但它作为后台任务不会影响数据库或用户事务的可用性。 错误日志中可能会显示错误消息,指示清理操作因缺少列加密密钥而失败。
安全注意事项
下面的安全注意事项适用于含安全 enclave 的 Always Encrypted。
- VBS enclave 可帮助保护数据免受 VM 内部的攻击。 但是,VBS enclave 不使用源自主机的特权系统帐户来提供任何攻击保护。 Intel SGX enclave 可保护数据免受来自来宾 OS 和主机 OS 的攻击。
- 如果你的环境可以使用 enclave 证明,并且需要防范对托管数据库的计算机具有操作系统级管理员访问权限的用户攻击你的数据,则建议使用 enclave 证明。 如果使用证明,则需要确保证明服务及其配置由受信任的管理员管理。 此外,两种支持的证明服务还提供不同的策略和证明模式,其中一些对 enclave 及其环境执行最小验证,旨在用于测试和开发目的。 请严格遵循证明服务专用指南,确保为生产部署使用建议的配置和策略。
- 如果结合使用随机加密和已启用 enclave 的列加密密钥来加密列,可能会导致列中存储的数据顺序泄露,因为此类列支持范围比较。 例如,如果包含员工薪金的加密列有索引,恶意 DBA 可以通过扫描此索引来查找最高加密薪金值,并确定薪金最高的员工(假设员工姓名未加密)。
- 如果使用 Always Encrypted 来防止 DBA 未经授权地访问敏感数据,请不要将列 master密钥或列加密密钥与 DBA 共享。 通过使用 enclave 内的列加密密钥缓存,DBA 无需拥有对密钥的直接访问权限即可管理加密列上的索引。
业务连续性、灾难恢复和数据迁移的注意事项
使用具有安全 enclave 的 Always Encrypted 为数据库配置高可用性或灾难恢复解决方案时,请确保所有数据库副本均可使用安全 enclave。 如果 enclave 可用于主要副本,但不可用于次要副本,则在故障转移后,任何尝试使用具有安全 enclave 的 Always Encrypted 功能的语句都将失败。
使用具有安全 enclave 的 Always Encrypted 复制或迁移数据库时,请确保目标环境始终支持 enclave。 否则,使用 enclave 的语句将不适用于副本或迁移的数据库。
下面是应注意的一些具体事项:
- SQL Server - 配置 AlwaysOn 可用性组时,请确保在可用性组中托管数据库的每个 SQL Server 实例都支持具有安全 enclave 的 Always Encrypted,并且已配置 enclave 和证明。
- 如果数据库使用具有安全 enclave 的 Always Encrypted 功能,同时你在未配置 enclave 的 SQL Server 实例上还原它的备份文件,还原操作会成功,且不依赖 enclave 的所有功能都可用。 不过,所有使用 enclave 功能的后续语句都会失败,使用随机加密且已启用 enclave 的列上的索引也会失效。 在未配置 enclave 的实例上附加使用含安全 enclave 的 Always Encrypted 的数据库时,亦是如此。
- 如果数据库包含使用随机加密且已启用 enclave 的列上的索引,请确保先在数据库中启用加速数据库恢复 (ADR),再创建数据库备份。 ADR 可确保数据库(包括索引)在你还原数据库后立即可用。 有关详细信息,请参阅数据库恢复。
 
- Azure SQL 数据库 - 在配置活动异地复制时,如果主数据库支持安全 enclave,请确保辅助数据库也支持。
 
在 SQL Server 和 Azure SQL 数据库中,使用 bacpac 文件迁移数据库时,必须确保先删除使用随机加密且已启用 enclave 的列上的所有索引,再创建 bacpac 文件。
已知的限制
具有安全 enclave 的 Always Encrypted 通过对索引支持就地加密和更丰富的机密查询来解决 Always Encrypted 的某些限制问题,如已启用 enclave 的列的机密计算功能中所述。
限制中列出的所有其他 Always Encrypted 限制也适用于具有安全 enclave 的 Always Encrypted。
下面介绍了含安全 enclave 的 Always Encrypted 的专属限制:
- 无法在使用随机加密且已启用 enclave 的列上创建聚集索引。
- 使用随机加密且已启用 enclave 的列无法作为主键列,并且无法被外键约束或唯一键约束引用。
- 在 SQL Server 2019 (15.x)(此限制不适用于 Azure SQL 数据库或 SQL Server 2022 (16.x))中,使用随机加密的启用 Enclave 的列仅支持嵌套循环联接(在可用时使用索引)。 有关不同产品间的其他差异的信息,请参阅机密查询。
- 就地加密操作无法与列元数据的其他任何更改合并,更改同一代码页内的排序规则以及更改为 Null 性除外。 例如,不能在单个 ALTER TABLE/ALTER COLUMNTransact-SQL 语句中加密、重新加密或解密列并更改列的数据类型。 请单独使用两个语句。
- 不支持将已启用 enclave 的密钥用于内存中表内的列。
- 定义计算列的表达式无法对使用随机加密且已启用 enclave 的列执行任何计算(即使这些计算属于机密查询中列出的受支持操作)。
- 在使用随机加密且已启用 enclave 的列上,LIKE 运算符的参数中不支持转义字符。
- 如果查询中的 LIKE 运算符或比较运算符包含使用以下数据类型(加密后成为大型对象)之一的查询参数,查询会忽略索引,并执行表扫描。
- nchar[n]和- nvarchar[n](如果 n 大于 3967)。
- char[n]、- varchar[n]、- binary[n]、- varbinary[n](如果 n 大于 7935)。
 
- 用于存储已启用 enclave 的列 master密钥的唯一受支持密钥存储是 Windows 证书存储和 Azure Key Vault。
- 还原已启用 VBS enclave 的数据库时,必须重新配置 VBS enclave 设置。