Always Encrypted - 针对加密列的查询的工作原理
适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例
若要对加密的数据库列执行查询,请将数据插入这些列,检索纯文本值,或使用确定性加密执行支持的操作(如点查找搜索),发出查询的用户或应用程序必须满足以下先决条件:
- 有权访问保护数据的列主密钥。 除了数据库级权限之外,还需要此密钥访问,例如相关表上的 SELECT。
- 连接到数据库,同时在数据库连接中启用 Always Encrypted。 大多数 SQL 工具和 SQL 客户端驱动程序都支持为数据库连接启用 Always Encrypted。
注意
如果用户具有读取数据所需的数据库权限,但无法访问保护数据的密钥,则用户仍可以通过连接到数据库来检索 cyphertext (加密) 数据,而无需在数据库连接中启用 Always Encrypted。
下面是对加密列进行查询的工作原理:
- 当应用程序发出参数化查询时,应用程序中的 SQL 客户端驱动程序以透明方式联系数据库引擎(通过调用sp_describe_parameter_encryption来确定哪些参数以加密列为目标并应加密。 对于需要加密的每个参数,驱动程序将接收加密算法、加密类型和密钥元数据,包括加密列加密密钥及其相应列主密钥的位置。
- 驱动程序会调用包含列主密钥的密钥存储,以解密加密列的加密密钥值。 产生的纯文本列加密密钥已缓存,以便在以后使用相同的列加密密钥时减少对密钥存储的往返访问次数。
- 驱动程序使用获取的纯文本列加密密钥来加密对应加密列的查询参数。
- 驱动程序将指向加密列的参数的纯文本值替换为它们的加密值,并将查询发送到数据库引擎以进行处理。
- 数据库引擎执行查询,这可能涉及使用确定性加密对列进行相等比较。
- 如果查询结果包括来自加密列的数据,则数据库引擎会将每个列的加密元数据附加到结果集中,其中包括有关加密算法、加密类型和密钥元数据的信息。
- 数据库引擎将结果集发送到客户端应用程序。
- 对于接收的结果集中的每个加密列,驱动程序首先尝试在本地缓存中查找纯文本列加密密钥,如果无法在缓存中找到该密钥,则只访问持有列主密钥的密钥存储库。
- 驱动程序解密结果并将纯文本值返回给应用程序。
客户端驱动程序使用列主密钥存储提供程序与包含列主密钥的密钥存储进行交互,列主密钥存储提供程序是一个客户端软件组件,用于封装包含列主密钥的密钥存储。 常见类型的密钥存储的提供程序在 Microsoft 的客户端驱动程序库中提供,或作为单独的软件下载。 你也可以实现自己的提供程序。 Always Encrypted 功能(包括内置的列主密钥存储提供程序)因驱动程序库及其版本而异。
有关支持 Always Encrypted 的客户端驱动程序列表以及有关如何开发查询加密列的应用程序的信息,请参阅使用 Always Encrypted 开发应用程序。
还可以使用 SQL 工具查询加密列,例如将 Always Encrypted 与 Azure Data Studio 配合使用的查询列,或者通过 SQL Server Management Studio 使用 Always Encrypted 查询列。