阐释对象加密和安全 enclave

已完成

除了支持静态加密外,SQL Server 还支持使用 Always Encrypted 对列中的数据进行加密。 加密数据后,访问数据库的应用程序必须具有正确的证书才能查看数据的纯文本值。

Always Encrypted

Always Encrypted 允许对客户端应用程序中的数据进行加密,保护敏感数据免受恶意软件和高特权用户(例如数据库管理员 (DBA)、服务器管理员、云管理员或管理数据但不应具有访问权限的用户)的侵害。 此加密根据 Microsoft SQL Server 数据库中的设置自动发生,该数据库会将数据库列的加密设置告知应用程序。

下表提供了 Always Encrypted 用法的一些场景:

方案 定义
客户端和数据都在本地 对于需要保护本地数据库免受高特权用户(例如,管理 SQL Server 的外部供应商)侵害的情况。
客户端在本地,数据在 Azure 中 在这种情况下,为确保 Microsoft 云管理员无法访问数据,Always Encrypted 密钥存储在本地托管的密钥存储中,用于在 Microsoft Azure 上的虚拟机中运行的 SQL 数据库或 SQL Server。
客户端和数据都在 Azure 中 在这种情况下,环境完全托管在 Azure 上。 虽然 Always Encrypted 并未将数据与云管理员完全隔离开,但客户仍然受益于数据在数据库中加密的事实。

Always Encrypted 基于主加密密钥和列加密密钥。 同时拥有这两个密钥,可使用不同的加密密钥来加密每个列,以实现最大程度的数据保护。 Always Encrypted 具有各种密钥存储,可存储加密所使用的证书。

下面是启用 Always Encrypted 的示例。 如下所示,可以看到 NationalIDNumber 和 BirthDate 列均为纯文本。

Query from Unencrypted table for Always Encrypted.

接下来的几张图将展示如何使用 Always Encrypted 来加密这两个列。 加密可以使用 T-SQL 完成,但在此示例中,你将看到 SQL Server Management Studio 中的向导。 可以通过在对象资源管理器中右键单击表名称来访问该向导,如下所示。

Launching the Encryption Wizard in SQL Server Management Studio.

选择“加密列...”后,向导将启动。

Always Encrypted Wizard launch screen from SSMS.

在下图中,你将看到 Always Encrypted 启动屏幕。 选择“下一步”以选择要加密的列。

Column selection screen for Always Encrypted Wizard.

在上图中,指定了两种不同类型的加密。 使用“确定性”加密来加密 NationalIDNumber 列,使用“随机”加密来加密 BirthDate 列。

随机加密比确定性加密更安全,但受到更多限制。 创建列后,不能更改加密类型。 对于包含有权访问加密值的人可能猜出的少量已知非重复值的列,建议使用“随机”加密。 可能猜出的列的一个示例是三位数的信用卡验证码。

使用具有“随机”加密的 Always Encrypted 会受到更多限制,因为随机化意味着相同的值并不总是以相同的方式进行加密。 对于使用了随机加密的列,唯一可以执行的操作是在结果中返回这些列。 “确定性”加密始终将值编码为同一字符串,这样我们就可以使用相等和不相等运算符将列与常量进行比较,并相互比较列来执行联接、分组和索引。

需要注意的另一点是,向导将生成列加密密钥,它是实际执行数据加密的密钥。 可以对每个被加密的列使用其自己的密钥,也可以使用相同的密钥来加密这两列,如此处所示。

确定要加密的列后,可以选择“下一步”,将显示“主密钥配置”屏幕:

Master Key Configuration for Always Encrypted Wizard.

在此屏幕中,你将创建用于加密列加密密钥的列主密钥。 如果使用 T-SQL 对列进行加密,可以提供自己的密钥。 此密钥必须存储在密钥存储中,例如 Windows 证书存储、Azure Key Vault 或硬件安全模块。 数据库引擎从不存储列主密钥,而仅包含有关存储位置的元数据。 不存储主密钥可防止对数据库具有完全访问权限的用户进行数据访问。

为实现最高级别的安全性,密钥应存储在第三方密钥存储中,如 Azure Key Vault。 请勿在承载数据库的服务器上生成密钥,因为可能有人会从该服务器上的内存中提取该密钥。

在下面的示例中,密钥存储在 Azure Key Vault 中。 在下一个屏幕上,向导将提供选项,让你选择是立即完成加密过程还是生成 PowerShell 脚本。 完成此过程后,对于没有密钥而查询数据的任何人,数据都将显示为已加密。

Employees Table with Encrypted Data from SSMS.

为解密 Always Encrypted 列中的数据,应用程序需要一个 Always Encrypted 驱动程序以连接到数据库,然后执行以下操作:

  1. 应用程序可以访问存储 Always Encrypted 密钥的密钥存储
  2. 然后该应用程序检索数据
  3. 写回数据库的数据在客户端通过驱动程序加密

除驱动程序外,应用程序的连接字符串还需要提供“Column Encryption Setting=enabled”设置。 此设置将导致对应用程序使用的每个列进行元数据查找。

注意

为了最大程度地减少元数据查找,应用程序需要更新 .NET 应用程序内 SqlConnection 对象上的 SqlCommandColumnEncryptionSetting。 必须为应用程序提交的每个数据库查询进行这些设置。

安全 enclave

Always Encrypted 支持名为安全 enclave 的功能,该功能允许对加密数据进行更可靠的查询。

安全 enclave 是 SQL Server 进程中受保护的内存区域,它充当用于处理加密数据的受信任的执行环境。 此 enclave 对 SQL Server 显示为黑色的框,即使使用调试器也无法查看任何数据或代码。

下图显示了此过程的体系结构:

Secure Enclaves Architecture for Always Encrypted.

具有安全 enclave 的 Always Encrypted 还解决了“随机”加密的一些限制,从而允许对使用此加密类型的列进行模式匹配、比较操作和编制索引。