使用 Azure Key Vault 为 Azure Cosmos 帐户配置客户管理的密钥

适用于: SQL API Cassandra API Gremlin API 表 API Azure Cosmos DB API for MongoDB

存储在 Azure Cosmos 帐户中的数据会使用 Azure 托管密钥(服务托管密钥)自动无缝地进行加密。 还可以选择使用你自己托管的密钥(客户托管密钥)来添加另一个加密层。

围绕客户数据的加密层

必须将客户托管密钥存储在 Azure Key Vault 中,并为每个启用了客户托管密钥的 Azure Cosmos 帐户提供一个密钥。 此密钥用于加密存储在该帐户中的所有数据。

备注

当前,客户托管密钥仅适用于新的 Azure Cosmos 帐户。 应在创建帐户期间配置这些密钥。

为 Azure 订阅注册 Azure Cosmos DB 资源提供程序

  1. 登录到 Azure 门户,转到 Azure 订阅,并在 “设置” 选项卡下选择 “资源提供程序”

    左侧菜单中的“资源提供程序”项

  2. 搜索“Microsoft DocumentDB”资源提供程序。 确认该资源提供程序是否标记为已注册。 如果不是,请选择该资源提供程序,然后选择“注册”:

    注册“Microsoft DocumentDB”资源提供程序

配置 Azure Key Vault 实例

将客户管理的密钥与 Azure Cosmos DB 结合使用时,需要在计划用于托管加密密钥的 Azure Key Vault 实例上设置两个属性: “软删除”“清除保护”

如果创建新的 Azure Key Vault 实例,请在创建过程中启用以下属性:

为新的 Azure Key Vault 实例启用“软删除”和“清除保护”

如果使用的是现有 Azure Key Vault 实例,则可以通过查看 Azure 门户中的“属性”部分来验证是否已启用这些属性。 如果未启用任一属性,请参阅以下文章中的“启用软删除”和“启用清除保护”部分:

将访问策略添加到 Azure Key Vault 实例

  1. 在 Azure 门户中,转到你打算用来托管加密密钥的 Azure Key Vault 实例。 在左侧菜单中选择“访问策略”:

    左侧菜单中的“访问策略”

  2. 选择“+ 添加访问策略”。

  3. 在“密钥权限”下拉菜单中,选择“获取”、“解包密钥”和“包装密钥”权限:

    选择适当的权限

  4. 在“选择主体”下,选择“未选择任何项”。

  5. 搜索“Azure Cosmos DB”主体并将其选中(为了便于查找,对于任何 Azure 中国区域,还可以按主体 ID a232010e-820c-4083-83bb-3ace5fc29d0b 进行搜索)。 如果列表中没有“Azure Cosmos DB”主体,可能需要根据本文的注册资源提供程序部分所述,重新注册 Microsoft.DocumentDB 资源提供程序)。

    备注

    这样便可在 Azure Key Vault 访问策略中注册 Azure Cosmos DB 第一方标识。 若要将第一方标识替换为 Azure Cosmos DB 帐户托管标识,请参阅使用 Azure Key Vault 访问策略中的托管标识

  6. 选择底部的“选择”。

    选择 Azure Cosmos DB 主体

  7. 选择“添加”以添加新的访问策略。

  8. 在密钥保管库实例上选择“保存”,以保存所有更改。

在 Azure Key Vault 中生成密钥

  1. 在 Azure 门户中,转到你打算用来托管加密密钥的 Azure Key Vault 实例。 然后,从左侧菜单中选择“密钥”:

    左侧菜单中的“密钥”项

  2. 选择“生成/导入”,为新密钥提供名称,并选择一个 RSA 密钥大小。 建议至少使用 3072,以获得最佳安全性。 然后选择“创建”:

    新建密钥

  3. 创建密钥后,选择新创建的密钥,然后选择其当前版本。

  4. 复制密钥的密钥标识符(最后一个正斜杠之后的部分除外):

    复制密钥的密钥标识符

创建新的 Azure Cosmos 帐户

使用 Azure 门户

当你从 Azure 门户创建新的 Azure Cosmos DB 帐户时,请选择“加密”步骤中“客户管理的密钥”。 在“密钥 URI”字段中,粘贴从上一步复制的 Azure Key Vault 密钥的 URI/密钥标识符:

在 Azure 门户中设置 CMK 参数

使用 Azure PowerShell

使用 PowerShell 创建新的 Azure Cosmos DB 帐户时:

  • 在“PropertyObject”中,传递前面在“keyVaultKeyUri”属性下复制的 Azure Key Vault 密钥的 URI。

  • 使用 2019-12-12 或更高版本作为 API 版本。

重要

必须显式设置 locations 属性,才能通过客户管理的密钥成功创建帐户。

$resourceGroupName = "myResourceGroup"
$accountLocation = "China North 2"
$accountName = "mycosmosaccount"

$failoverLocations = @(
    @{ "locationName"="China North 2"; "failoverPriority"=0 }
)

$CosmosDBProperties = @{
    "databaseAccountOfferType"="Standard";
    "locations"=$failoverLocations;
    "keyVaultKeyUri" = "https://<my-vault>.vault.azure.cn/keys/<my-key>";
}

New-AzResource -ResourceType "Microsoft.DocumentDb/databaseAccounts" `
    -ApiVersion "2019-12-12" -ResourceGroupName $resourceGroupName `
    -Location $accountLocation -Name $accountName -PropertyObject $CosmosDBProperties

创建帐户后,可以通过提取 Azure Key Vault 密钥的 URI 来验证是否已启用客户管理的密钥:

Get-AzResource -ResourceGroupName $resourceGroupName -Name $accountName `
    -ResourceType "Microsoft.DocumentDb/databaseAccounts" `
    | Select-Object -ExpandProperty Properties `
    | Select-Object -ExpandProperty keyVaultKeyUri

使用 Azure 资源管理器模板

通过 Azure 资源管理器模板创建新的 Azure Cosmos 帐户时:

  • 在“属性”对象中,传递前面在“keyVaultKeyUri”属性下复制的 Azure Key Vault 密钥的 URI。

  • 使用 2019-12-12 或更高版本作为 API 版本。

重要

必须显式设置 locations 属性,才能通过客户管理的密钥成功创建帐户。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "accountName": {
            "type": "string"
        },
        "location": {
            "type": "string"
        },
        "keyVaultKeyUri": {
            "type": "string"
        }
    },
    "resources": 
    [
        {
            "type": "Microsoft.DocumentDB/databaseAccounts",
            "name": "[parameters('accountName')]",
            "apiVersion": "2019-12-12",
            "kind": "GlobalDocumentDB",
            "location": "[parameters('location')]",
            "properties": {
                "locations": [ 
                    {
                        "locationName": "[parameters('location')]",
                        "failoverPriority": 0,
                        "isZoneRedundant": false
                    }
                ],
                "databaseAccountOfferType": "Standard",
                "keyVaultKeyUri": "[parameters('keyVaultKeyUri')]"
            }
        }
    ]
}

使用以下 PowerShell 脚本部署模板:

$resourceGroupName = "myResourceGroup"
$accountName = "mycosmosaccount"
$accountLocation = "China North 2"
$keyVaultKeyUri = "https://<my-vault>.vault.azure.cn/keys/<my-key>"

New-AzResourceGroupDeployment `
    -ResourceGroupName $resourceGroupName `
    -TemplateFile "deploy.json" `
    -accountName $accountName `
    -location $accountLocation `
    -keyVaultKeyUri $keyVaultKeyUri

使用 Azure CLI

通过 Azure CLI 创建新的 Azure Cosmos 帐户时,传递前面在 --key-uri 参数下复制的 Azure Key Vault 密钥的 URI。

resourceGroupName='myResourceGroup'
accountName='mycosmosaccount'
keyVaultKeyUri = 'https://<my-vault>.vault.azure.cn/keys/<my-key>'

az cosmosdb create \
    -n $accountName \
    -g $resourceGroupName \
    --locations regionName='China North 2' failoverPriority=0 isZoneRedundant=False \
    --key-uri $keyVaultKeyUri

创建帐户后,可以通过提取 Azure Key Vault 密钥的 URI 来验证是否已启用客户管理的密钥:

az cosmosdb show \
    -n $accountName \
    -g $resourceGroupName \
    --query keyVaultKeyUri

使用 Azure Key Vault 访问策略中的托管标识

此访问策略确保你的 Azure Cosmos DB 帐户可以访问你的加密密钥。 这是通过授予对特定 Azure Active Directory (AD) 标识的访问权限来实现的。 支持两种类型的标识:

  • Azure Cosmos DB 的第一方标识,可用于授予对 Azure Cosmos DB 服务的访问权限。
  • Azure Cosmos DB 帐户的托管标识,可用于专门授予对帐户的访问权限。

由于只有在创建帐户后才能检索系统分配的托管标识,因此你仍然需要首先使用第一方标识创建你的帐户,如上所述。 那么:

  1. 如果在创建帐户过程中未完成此操作,请在你的帐户上启用系统分配的托管标识并复制分配的 principalId

  2. 如上所述,向 Azure Key Vault 帐户添加新的访问策略,但使用在上一步中复制的 principalId,而不是 Azure Cosmos DB 的第一方标识。

  3. 更新 Azure Cosmos DB 帐户,以指定在访问 Azure Key Vault 中的加密密钥时要使用系统分配的托管标识。 为此,可执行以下操作:

    • 在帐户的 Azure 资源管理器模板中指定以下属性:

      {
          "type": " Microsoft.DocumentDB/databaseAccounts",
          "properties": {
              "defaultIdentity": "SystemAssignedIdentity",
              // ...
          },
          // ...
      }
      
    • 使用 Azure CLI 更新帐户:

      resourceGroupName='myResourceGroup'
      accountName='mycosmosaccount'
      
      az cosmosdb update --resource-group $resourceGroupName --name $accountName --default-identity "SystemAssignedIdentity"
      
  4. (可选)然后从 Azure Key Vault 访问策略中删除 Azure Cosmos DB 第一方标识。

密钥轮换

可以通过两种方式来轮换 Azure Cosmos 帐户使用的客户托管密钥。

  • 创建当前在 Azure Key Vault 中使用的密钥的新版本:

    创建新的密钥版本

  • 通过更新帐户的密钥 URI,将当前使用的密钥与完全不同的密钥交换。 在 Azure 门户中转到你的 Azure Cosmos 帐户,然后在左侧菜单中选择“数据加密”:

    “数据加密”菜单项

    然后,将“密钥 URI”替换为要使用的新密钥,并选择“保存”:

    更新密钥 URI

    下面介绍如何在 PowerShell 中实现相同的结果:

    $resourceGroupName = "myResourceGroup"
    $accountName = "mycosmosaccount"
    $newKeyUri = "https://<my-vault>.vault.azure.cn/keys/<my-new-key>"
    
    $account = Get-AzResource -ResourceGroupName $resourceGroupName -Name $accountName `
        -ResourceType "Microsoft.DocumentDb/databaseAccounts"
    
    $account.Properties.keyVaultKeyUri = $newKeyUri
    
    $account | Set-AzResource -Force
    

可以在 Azure Key Vault 审核日志不再显示该密钥或密钥版本 Azure Cosmos DB 中的活动之后禁用以前的密钥或密钥版本。 在密钥轮换 24 小时后,不应在以前的密钥或密钥版本上进行更多活动。

错误处理。

在 Azure Cosmos DB 中使用客户托管密钥 (CMK) 时,如果存在任何错误,Azure Cosmos DB 会在响应中返回错误详细信息以及 HTTP 子状态代码。 可以使用此子状态代码来调试问题的根本原因。 请参阅 Azure Cosmos DB 的 HTTP 状态代码一文获取支持的 HTTP 子状态代码的列表。

常见问题

启用客户管理的密钥是否额外收费?

否,启用此功能不收取任何费用。

客户管理的密钥会对容量计划产生怎样的影响?

使用客户管理的密钥时,数据库操作使用的请求单位会增加,以反映执行加密和解密数据所需的额外处理。 这可能会导致预配容量的利用率略高。 请参阅下表中的指南:

操作类型 请求单位增加
点读取(按 ID 获取项) 每个操作 + 5%
任何写入操作 每个操作 + 6%
每个索引属性约为 + 0.06 RU
查询、读取更改源或冲突源 每个操作 + 15%

哪些数据是通过客户管理的密钥加密的?

Azure Cosmos 帐户中存储的所有数据都将通过客户托管密钥加密,但以下元数据除外:

现有的 Azure Cosmos 帐户是否支持客户管理的密钥?

此功能目前仅适用于新帐户。

能否将客户管理的密钥与 Azure Cosmos DB 分析存储结合使用?

可以,Azure Synapse Link 仅支持使用 Azure Cosmos DB 帐户的托管标识配置客户管理的密钥。 在帐户上启用 Azure Synapse Link 之前,必须在 Azure Key Vault 访问策略中使用 Azure Cosmos DB 帐户的托管标识

是否有计划支持比帐户级别密钥更精细的粒度?

目前没有,但正在考虑容器级别的密钥。

如何判断是否在 Azure Cosmos 帐户上启用了客户管理的密钥?

在 Azure 门户中,转到 Azure Cosmos 帐户,并在左侧菜单中查看“数据加密”项;如果此项存在,则在帐户中启用了客户管理的密钥:

“数据加密”菜单项

还可以通过编程方式提取 Azure Cosmos 帐户的详细信息,并查找 keyVaultKeyUri 属性是否存在。 请参阅上面的方法,在 PowerShell 中使用 Azure CLI. 实现此操作。

客户管理的密钥如何影响备份?

Azure Cosmos DB 将定期自动备份存储在帐户中的数据。 此操作可备份加密的数据。 若要使用还原的备份,需要在备份时使用的加密密钥。 这意味着,没有执行任何吊销操作,并且备份时使用的密钥版本仍将保持启用状态。

如何吊销加密密钥?

密钥吊销是通过禁用密钥的最新版本来完成的:

禁用密钥的版本

或者,若要从 Azure Key Vault 实例撤消所有密钥,可以删除授予 Azure Cosmos DB 主体的访问策略:

删除 Azure Cosmos DB 主体的访问策略

吊销客户管理的密钥后可执行哪些操作?

吊销加密密钥后,删除帐户是唯一可执行的操作。

后续步骤