适用于: SQL Server 2019 (15.x) 及更高版本 - 仅限 Windows
Azure SQL 数据库
本文介绍如何预配已启用 enclave 的密钥,这些密钥支持用于具有安全 enclave 的 Always Encrypted 的服务器端安全 enclave 中的计算。
管理 Always Encrypted 密钥的一般准则和流程在预配已启用 enclave 的密钥时适用。 本文介绍特定于具有安全 enclave 的 Always Encrypted 的详细信息。
若要使用 SQL Server Management Studio 或 PowerShell 预配已启用 enclave 的列主密钥,请确保新密钥支持 enclave 计算。 这会导致工具(SSMS 或 PowerShell)生成 CREATE COLUMN MASTER KEY
语句,该语句在数据库的列主密钥元数据中设置 ENCLAVE_COMPUTATIONS
。 有关详细信息,请参阅 CREATE COLUMN MASTER KEY (Transact-SQL)。
该工具还会使用列主密钥对列主属性进行数字签名,并将签名存储在数据库元数据中。 此签名可防止恶意篡改 ENCLAVE_COMPUTATIONS
设置。 SQL 客户端驱动程序验证签名之后才会允许使用 enclave。 这使安全管理员能够控制哪些列数据可以在安全区内进行计算。
ENCLAVE_COMPUTATIONS
是不可变的,也就是说,在元数据中定义列主密钥后无法更改它。 若要启用使用列加密密钥(使用给定列主密钥进行加密)的 enclave 计算,需要轮换列主密钥并将其替换为已启用 enclave 的列主密钥。 请参阅轮换已启用 enclave 功能的密钥。
注意
当前,SSMS 和 PowerShell 都支持 Azure 密钥保管库或 Windows 证书存储中存储的已启用 enclave 的列主密钥。 不支持硬件安全模块(使用 CNG 或 CAPI)。
若要创建已启用 enclave 的列加密密钥,需要确保选择已启用 enclave 的列主密钥来加密新密钥。
以下部分提供有关如何使用 SSMS 和 PowerShell 预配已启用 enclave 的密钥的更多详细信息。
使用 SQL Server Management Studio 配置启用 enclave 的密钥
在 SQL Server Management Studio 中,可以预配:
- 已启用 enclave 的列主密钥(使用“新建列主密钥”对话框)。
- 已启用 enclave 的列加密密钥(使用“新建列加密密钥”对话框)。
借助 Always Encrypted 向导,还可以创建已启用 Enclave 的列主密钥和已启用 Enclave 的列加密密钥。
请务必已安装 SQL Server Management Studio (SSMS) 的最新正式发布 (GA) 版。
使用“新建列主密钥”对话框预配已启用 enclave 的列主密钥
若要预配已启用 enclave 的列主密钥,请按照使用“新建列主密钥”对话框预配列主密钥中的步骤进行操作。 确保选择“允许 enclave 计算”。 请参阅以下屏幕截图:
注意
仅在为数据库配置了安全 enclave 时,才会显示“允许 enclave 计算”复选框。 如果您使用的是 SQL Server,可以查看 在 SQL Server 中配置安全区。 如果您正在使用 Azure SQL 数据库,请参阅 为 Azure SQL 数据库启用 Always Encrypted 功能并配置安全区域。
提示
若要检查列主密钥是否已启用 enclave,请在对象资源管理器中右键单击它,然后选择“属性”。 如果密钥已启用 Enclave,则显示键属性的窗口中将会显示“Enclave 计算:允许”。 或者,可以使用 sys.column_master_keys (Transact-SQL) 视图。
使用“新建列加密密钥”对话框预配已启用 enclave 的列加密密钥
若要预配已启用 enclave 的列加密密钥,请按照使用“新建列加密密钥”对话框预配列加密密钥中的步骤进行操作。 选择列主密钥时,请确保它支持 enclave 功能。
提示
若要检查列加密密钥是否已启用 enclave,请在对象资源管理器中右键单击它,然后选择“属性”。 如果密钥已启用 Enclave,则显示键属性的窗口中将会显示“Enclave 计算:允许”。
使用 PowerShell 配置启用 enclave 的密钥
要使用 PowerShell 预配已启用 Enclave 的密钥,需要 SqlServer Powershell 模块版本 22 或更高版本。
一般而言,为 Always Encrypted 提供 PowerShell 密钥的预配工作流(在 使用 PowerShell 预配 Always Encrypted 密钥 中进行了介绍),无论是否有角色分离,也适用于 enclave 支持的密钥。 此部分介绍特定于已启用 enclave 的密钥的详细信息。
SqlServer PowerShell 模块通过 -AllowEnclaveComputations
参数扩展了 New-SqlCertificateStoreColumnMasterKeySettings 和 New-SqlAzureKeyVaultColumnMasterKeySettings cmdlet,使您可以在预配过程中指定启用了 enclave 的列主密钥。 任一 cmdlet 都会创建包含列主密钥(存储在 Azure Key Vault 或 Windows 证书存储中)的属性的本地对象。 如果指定,则 -AllowEnclaveComputations
属性会在本地对象中将密钥标记为已启用 enclave。 它还会使 cmdlet 访问所引用的列主密钥(在 Azure Key Vault 或 Windows 证书存储中)以对密钥的属性进行数字签名。 为新的已启用 enclave 的列主密钥创建设置对象后,便可以在 New-SqlColumnMasterKey cmdlet 的后续调用中使用它,以在数据库中创建描述新密钥的元数据对象。
预配已启用 enclave 的列加密密钥与预配未启用 enclave 的列加密密钥没有什么不同。 只需确保用于加密新的列加密密钥的列主密钥已启用 enclave。
注意
SqlServer PowerShell 模块当前不支持预配存储在硬件安全模块(使用 CNG 或 CAPI)中的已启用 enclave 的密钥。
示例 - 使用 Windows 证书存储预配已启用 enclave 的密钥
下面的端到端示例演示如何预配已启用 enclave 的密钥(将列主密钥存储在 Windows 证书存储中)。 该脚本基于不使用角色分隔的 Windows 证书存储(示例)中的示例。 请务必注意 -AllowEnclaveComputations
参数在 New-SqlCertificateStoreColumnMasterKeySettings cmdlet 中的使用,这是两个示例中的工作流之间的唯一区别。
# Create a column master key in Windows Certificate Store.
$cert = New-SelfSignedCertificate -Subject "AlwaysEncryptedCert" -CertStoreLocation Cert:CurrentUser\My -KeyExportPolicy Exportable -Type DocumentEncryptionCert -KeyUsage DataEncipherment -KeySpec KeyExchange
# Import the SqlServer module.
Import-Module "SqlServer" -MinimumVersion 22.0.50
# Connect to your database.
$serverName = "<server name>"
$databaseName = "<database name>"
# Change the authentication method in the connection string, if needed.
$connStr = "Server = " + $serverName + "; Database = " + $databaseName + "; Integrated Security = True; TrustServerCertificate = True"
$database = Get-SqlDatabase -ConnectionString $connStr
# Create a SqlColumnMasterKeySettings object for your column master key
# using the -AllowEnclaveComputations parameter.
$cmkSettings = New-SqlCertificateStoreColumnMasterKeySettings -CertificateStoreLocation "CurrentUser" -Thumbprint $cert.Thumbprint -AllowEnclaveComputations
# Create column master key metadata in the database.
$cmkName = "CMK1"
New-SqlColumnMasterKey -Name $cmkName -InputObject $database -ColumnMasterKeySettings $cmkSettings
# Generate a column encryption key, encrypt it with the column master key and create column encryption key metadata in the database.
$cekName = "CEK1"
New-SqlColumnEncryptionKey -Name $cekName -InputObject $database -ColumnMasterKey $cmkName
示例 - 使用 Azure Key Vault 预配已启用 enclave 的密钥
下面的端到端示例演示如何预配已启用 enclave 的密钥(将列主密钥存储在 Azure Key Vault 的密钥保管库中)。 该脚本基于不使用角色分隔的 Azure Key Vault(示例)中的示例。 请务必注意已启用 Enclave 的密钥与未启用 Enclave 的密钥相比,工作流之间有两个差异。
- 在下面的脚本中,New-SqlCertificateStoreColumnMasterKeySettings 使用
-AllowEnclaveComputations
参数使新的列主密钥启用 enclave。 - 以下脚本使用命令小程序 Get-AzAccessToken 来获取密钥保管库的访问令牌。 这是必需的,因为命令 New-SqlAzureKeyVaultColumnMasterKeySettings 需要访问 Azure Key Vault 以对列主密钥的属性进行签名。
# Create a column master key in Azure Key Vault.
Import-Module "SqlServer" -MinimumVersion 22.0.50
Import-Module Az.Accounts -MinimumVersion 2.2.0
Connect-AzAccount
$SubscriptionId = "<Azure SubscriptionId>"
$resourceGroup = "<resource group name>"
$azureLocation = "<datacenter ___location>"
$akvName = "<key vault name>"
$akvKeyName = "<key name>"
$azureCtx = Set-AzConteXt -SubscriptionId $SubscriptionId # Sets the context for the below cmdlets to the specified subscription.
New-AzResourceGroup -Name $resourceGroup -Location $azureLocation # Creates a new resource group - skip, if your desired group already exists.
New-AzKeyVault -VaultName $akvName -ResourceGroupName $resourceGroup -Location $azureLocation # Creates a new key vault - skip if your vault already exists.
Set-AzKeyVaultAccessPolicy -VaultName $akvName -ResourceGroupName $resourceGroup -PermissionsToKeys get, create, delete, list, wrapKey,unwrapKey, sign, verify -UserPrincipalName $azureCtx.Account
$akvKey = Add-AzKeyVaultKey -VaultName $akvName -Name $akvKeyName -Destination "Software"
# Connect to your database.
$serverName = "<server name>"
$databaseName = "<database name>"
# Change the authentication method in the connection string, if needed.
$connStr = "Server = " + $serverName + "; Database = " + $databaseName + "; Integrated Security = True; TrustServerCertificate = True"
$database = Get-SqlDatabase -ConnectionString $connStr
# Obtain an access token for key vaults.
$keyVaultAccessToken = (Get-AzAccessToken -ResourceUrl https://vault.azure.net).Token
# Create a SqlColumnMasterKeySettings object for your column master key.
$cmkSettings = New-SqlAzureKeyVaultColumnMasterKeySettings -KeyURL $akvKey.ID -AllowEnclaveComputations -KeyVaultAccessToken $keyVaultAccessToken
# Create column master key metadata in the database.
$cmkName = "CMK1"
New-SqlColumnMasterKey -Name $cmkName -InputObject $database -ColumnMasterKeySettings $cmkSettings
# Generate a column encryption key, encrypt it with the column master key and create column encryption key metadata in the database.
$cekName = "CEK1"
New-SqlColumnEncryptionKey -Name $cekName -InputObject $database -ColumnMasterKey $cmkName -KeyVaultAccessToken $keyVaultAccessToken
后续步骤
- 在安全隔离区内运行 Transact-SQL 语句
- 使用具有安全 Enclave 的 Always Encrypted 就地配置列加密
- 为现有加密列启用具有安全 enclave 的 Always Encrypted
- 使用具有安全隔离区的“始终加密”功能来开发应用程序