Amazon DynamoDB 如何使用 Amazon KMS - Amazon Key Management Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

Amazon DynamoDB 如何使用 Amazon KMS

Amazon DynamoDB 是一种完全托管的 NoSQL 数据库服务。DynamoDB 与 Amazon Key Management Service (Amazon KMS) 集成以支持静态加密服务器端加密功能。

利用静态加密,DynamoDB 可以透明方式对 DynamoDB 表中的所有客户数据进行加密,包括其主键及本地和全局二级索引,只要该表已保存到磁盘。(如果表具有排序键,则标记范围边界的一些排序键将以明文形式存储在表元数据中。) 当您访问表时,DynamoDB 会以透明方式解密表数据。您无需更改应用程序即可使用或管理加密表。

此外,在将 DynamoDB 流全局表备份保存到持久性媒体时,静态加密可以保护这些对象。有关本主题中表的语句也适用于这些对象。

将对所有 DynamoDB 表进行加密。没有为新表或现有表启用或禁用加密的选项。默认情况下,所有表都在 DynamoDB 服务账户中的 Amazon 拥有的密钥 下加密。但是,您可以选择一个选项来为您账户中的 DynamoDB 在客户托管密钥Amazon 托管式密钥 下对部分或全部表进行加密。

注意

在 2018 年 11 月之前,静态加密是一项可选功能,它仅支持适用于 DynamoDB 的 Amazon 托管式密钥。如果已对任意 DynamoDB 表启用静态加密,则这些表将继续在 Amazon 托管式密钥 下进行加密,除非使用 Amazon Web Services Management Console 或 UpdateTable 操作切换为客户托管密钥或 Amazon 拥有的密钥。

适用于 DynamoDB 的客户端加密

除了属于服务器端加密 功能的静态加密以外,Amazon 还提供 Amazon DynamoDB 加密客户端。此客户端加密 库使您能够在将表数据提交到 DynamoDB 之前对该数据进行保护。采用服务器端加密时,TLS 会通过 HTTPS 连接对传输中的数据进行加密。您的数据会在 DynamoDB 端点进行解密,并重新加密,然后存储在 DynamoDB 中。客户端加密在 DynamoDB 中为数据从其源到存储提供端到端保护,然后返回给您。

您可以将 DynamoDB 加密客户端与静态加密结合使用。要帮助您确定此策略是否适合您的 DynamoDB 数据,请参阅 Amazon DynamoDB 加密客户端开发人员指南中的客户端或服务器端加密?

使用 KMS 密钥和数据密钥

DynamoDB 静态加密功能使用 Amazon KMS key 和数据密钥的层次结构来保护表数据。DynamoDB 流、全局表和备份写入持久性媒体时,DynamoDB 使用相同的密钥层次结构来保护这些对象。

Amazon KMS key

静态加密功能在 Amazon KMS key 下保护您的 DynamoDB 表。默认情况下,DynamoDB 使用 Amazon 拥有的密钥,即在 DynamoDB 服务账户中创建并管理的多租户加密密钥。但是,您可以为您的 Amazon Web Services 账户 中的 DynamoDB (aws/dynamodb) 在客户托管密钥Amazon 托管式密钥 下对您的 DynamoDB 表进行加密。您可以为每个表选择不同的 KMS 密钥。您为表选择的 KMS 密钥也可用于加密其本地和全局二级索引、流和备份。

您可以在创建或更新表时为表选择 KMS 密钥。您可以通过以下方式随时更改表的 KMS 密钥:在 DynamoDB 控制台中或使用 UpdateTable 操作。切换密钥的过程是无缝的,不需要停机或降低服务质量。

重要

DynamoDB 仅支持对称 KMS 密钥。不能使用非对称 KMS 密钥来加密您的 DynamoDB 表。要获取确定 KMS 密钥是对称还是非对称的帮助,请参阅 识别对称 KMS 密钥和非对称 KMS 密钥

使用客户托管密钥可获得以下功能:

如果您需要以下任意功能,请使用 Amazon 托管式密钥:

但是,Amazon 拥有的密钥 是免费的,其使用不会计入 Amazon KMS 资源或请求配额。客户托管密钥和 Amazon 托管式密钥 针对每个 API 调用会产生费用,并且 Amazon KMS 配额适用于这些 KMS 密钥。

表密钥

DynamoDB 对表使用 KMS 密钥来生成和加密表的唯一数据密钥(也称作表密钥)。该表密钥将在加密表的生命周期内保留。

该表密钥用作密钥加密密钥。DynamoDB 使用此表密钥来保护用于加密表数据的数据加密密密钥。DynamoDB 会为表中的每个底层结构生成唯一的数据加密密钥,但多个表项目可能受相同的数据加密密钥保护。


              使用静态加密对 DynamoDB 表进行加密

当您首次访问加密表时,DynamoDB 会向 Amazon KMS 发送请求以使用 KMS 密钥解密表密钥。然后,它会使用明文表密钥来解密数据加密密钥,并使用明文数据加密密钥解密表数据。

DynamoDB 在 Amazon KMS 外部存储和使用表密钥与数据加密密钥。它会借助高级加密标准 (AES) 加密和 256 位加密密钥保护所有密钥。然后,它存储加密密钥及加密数据,以便它们可根据需要用于解密表数据。

如果更改表的 KMS 密钥,DynamoDB 会生成新的表密钥。然后,它使用新的表密钥来重新加密数据加密密钥。

表密钥缓存

为了避免针对每个 DynamoDB 操作调用 Amazon KMS,DynamoDB 会针对每个连接将明文表密钥缓存在内存中。如果 DynamoDB 在处于不活动状态 5 分钟后获取缓存表密钥的请求,它会向 Amazon KMS 发送新请求以解密表密钥。此调用将捕获自上次请求解密表密钥以来对 Amazon KMS 或 Amazon Identity and Access Management (IAM) 中的 KMS 密钥的访问策略所做的任何更改。

授权使用 KMS 密钥

如果您使用账户中的客户托管密钥Amazon 托管式密钥 保护您的 DynamoDB 表,则该 KMS 密钥的策略必须赋予 DynamoDB 代表您使用该 KMS 密钥的权限。适用于 DynamoDB 的 Amazon 托管式密钥 的授权上下文包括其密钥策略并授予该委托人使用此策略的权限。

您可以全面控制客户托管密钥的策略和授权,因为 Amazon 托管式密钥 在您的账户中,您可以查看其策略和授权。但由于它由 Amazon 托管,因此,您无法更改策略。

DynamoDB 无需额外授权即可使用默认的 Amazon 拥有的密钥 来保护您 Amazon Web Services 账户 中的 DynamoDB 表。

用于 Amazon 托管式密钥 的密钥策略

当 DynamoDB 在加密操作中为 DynamoDB (aws/dynamodb) 使用 Amazon 托管式密钥 时,它将代表正在访问 DynamoDB 资源的用户执行此操作。Amazon 托管式密钥 的密钥策略向账户中的所有用户授予对指定操作使用 Amazon 托管式密钥 的权限。但是,权限仅在 DynamoDB 代表用户提出请求时才被授予。密钥策略中的 ViaService 条件不允许任何用户使用 Amazon 托管式密钥,除非请求是通过 DynamoDB 服务发起的。

与所有 Amazon 托管式密钥 的策略类似,此密钥策略由 Amazon 建立。您无法更改它,但可以随时查看它。有关详细信息,请参阅查看密钥策略

密钥策略中的策略语句具有以下影响:

  • 仅当 DynamoDB 代表账户中的用户发出请求时,才允许这些用户在加密操作中将 Amazon 托管式密钥 用于 DynamoDB。该策略还允许用户为 KMS 密钥创建授权

  • 允许账户中的授权 IAM 身份查看对于 DynamoDB 的 Amazon 托管式密钥 的属性,并撤销允许 DynamoDB 使用 KMS 密钥的授权。DynamoDB 使用授权进行持续维护操作。

  • 允许 DynamoDB 执行只读操作来查找账户中的适用于 DynamoDB 的 Amazon 托管式密钥。

{ "Version" : "2012-10-17", "Id" : "auto-dynamodb-1", "Statement" : [ { "Sid" : "Allow access through Amazon DynamoDB for all principals in the account that are authorized to use Amazon DynamoDB", "Effect" : "Allow", "Principal" : { "AWS" : "*" }, "Action" : [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:CreateGrant", "kms:DescribeKey" ], "Resource" : "*", "Condition" : { "StringEquals" : { "kms:CallerAccount" : "111122223333", "kms:ViaService" : "dynamodb.us-west-2.amazonaws.com" } } }, { "Sid" : "Allow direct access to key metadata to the account", "Effect" : "Allow", "Principal" : { "AWS" : "arn:aws:iam::111122223333:root" }, "Action" : [ "kms:Describe*", "kms:Get*", "kms:List*", "kms:RevokeGrant" ], "Resource" : "*" }, { "Sid" : "Allow DynamoDB Service with service principal name dynamodb.amazonaws.com to describe the key directly", "Effect" : "Allow", "Principal" : { "Service" : "dynamodb.amazonaws.com" }, "Action" : [ "kms:Describe*", "kms:Get*", "kms:List*" ], "Resource" : "*" } ] }

客户托管密钥的密钥策略

如果选择客户托管密钥保护 DynamoDB 表,那么 DynamoDB 将获得代表做出选择的委托人使用 KMS 密钥的权限。该委托人(用户或角色)必须具有 DynamoDB 所需的 KMS 密钥权限。您可以在密钥策略IAM 策略授权中提供这些权限。

KMS 密钥 对客户托管密钥至少需要具备以下权限:

例如,以下示例密钥策略仅提供所需的权限。该策略具有以下效果:

  • 允许 DynamoDB 在加密操作中使用 KMS 密钥并创建授权,但仅当它代表账户中具备 DynamoDB 使用权限的委托人行事时才可如此。如果策略语句中指定的委托人无权使用 DynamoDB,调用将失败,即使调用来自 DynamoDB 服务也是如此。

  • kms:ViaService 条件键仅当 DynamoDB 代表策略语句中所列委托人发出请求时,才允许权限。这些委托人不能直接调用这些操作。请注意,kms:ViaServicedynamodb.*.amazonaws.com在“区域”位置中有一个星号 (*)。DynamoDB 要求权限独立于任何特定 Amazon Web Services 区域,以便它可以进行跨区域调用来支持 DynamoDB 全局表

  • 赋予 KMS 密钥管理员(可担任 db-team 角色的用户)对 KMS 密钥的只读访问权限,以及撤销授权的权限,包括 DynamoDB 保护表所需的授权

在使用示例密钥策略之前,请将示例委托人替换为 Amazon Web Services 账户 中的实际委托人。

{ "Id": "key-policy-dynamodb", "Version":"2012-10-17", "Statement": [ { "Sid" : "Allow access through Amazon DynamoDB for all principals in the account that are authorized to use Amazon DynamoDB", "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::111122223333:user/db-lead"}, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey", "kms:CreateGrant" ], "Resource": "*", "Condition": { "StringLike": { "kms:ViaService" : "dynamodb.*.amazonaws.com" } } }, { "Sid": "Allow administrators to view the KMS key and revoke grants", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/db-team" }, "Action": [ "kms:Describe*", "kms:Get*", "kms:List*", "kms:RevokeGrant" ], "Resource": "*" } ] }

使用授予来向 DynamoDB 授权

除密钥策略之外,DynamoDB 还使用授权来设置适用于 DynamoDB 的客户托管式密钥或 Amazon 托管式密钥 的权限 (aws/dynamodb)。要查看有关您账户中的 KMS 密钥的授权,请使用 ListGrants 操作。DynamoDB 不需要授权或任何其他权限即可使用 Amazon 拥有的密钥 来保护您的表。

DynamoDB 在执行后台系统维护和连续数据保护任务时使用授予权限。它还使用授权来生成表密钥

每个授权特定于一个表。如果账户中包含在同一 KMS 密钥下加密的多个表,则每个表都有一种授权。该授权受 DynamoDB 加密上下文约束,后者包括表名称和 Amazon Web Services 账户 ID,而且它还包括在授权不再需要时停用授权的权限。

要创建授权,DynamoDB 必须具备代表创建已加密表的用户调用 CreateGrant 的权限。对于 Amazon 托管式密钥,DynamoDB 将从密钥策略中获取 kms:CreateGrant 权限,以允许账户用户仅在 DynamoDB 代表授权用户发出请求时对 KMS 密钥调用 CreateGrant

该密钥策略还可以允许账户撤销对 KMS 密钥授权。但是,如果您对某个活动加密表撤销授权,DynamoDB 将无法保护和维护该表。

DynamoDB 加密上下文

加密上下文 是一组包含任意非机密数据的键值对。在请求中包含加密上下文以加密数据时,Amazon KMS 以加密方式将加密上下文绑定到加密的数据。要解密数据,您必须传入相同的加密上下文。

DynamoDB 在所有 Amazon KMS 加密操作中使用相同的加密上下文。如果您使用客户托管密钥Amazon 托管式密钥 保护 DynamoDB 表,则可使用加密上下文在审核记录和日志中标识 KMS 密钥的使用。它也以明文形式显示在日志中,例如 Amazon CloudTrailAmazon CloudWatch Logs

加密上下文还可以用作在策略和授权中进行授权的条件。DynamoDB 使用加密上下文来限制允许访问您的账户和区域中的客户托管密钥或 Amazon 托管式密钥 的授权

在请求 Amazon KMS 时,DynamoDB 使用具有两个密钥-值对的加密上下文。

"encryptionContextSubset": { "aws:dynamodb:tableName": "Books" "aws:dynamodb:subscriberId": "111122223333" }
  • – 第一个密钥-值对用于标识 DynamoDB 正在加密的表。密钥是 aws:dynamodb:tableName。值为表的名称。

    "aws:dynamodb:tableName": "<table-name>"

    例如:

    "aws:dynamodb:tableName": "Books"
  • 账户 – 第二个密钥-值对标识 Amazon Web Services 账户。密钥是 aws:dynamodb:subscriberId。该值为账户 ID。

    "aws:dynamodb:subscriberId": "<account-id>"

    例如:

    "aws:dynamodb:subscriberId": "111122223333"

监控 DynamoDB 与 Amazon KMS 的交互

如果使用客户托管式密钥Amazon 托管式密钥 保护您的 DynamoDB 表,您可使用 Amazon CloudTrail 日志跟踪 DynamoDB 代表您发送到 Amazon KMS 的请求。

本部分将讨论 GenerateDataKeyDecryptCreateGrant 请求。此外,DynamoDB 还使用 DescribeKey 操作来确定所选 KMS 密钥是否存在于账户和区域中。它还使用 RetireGrant 操作来在您删除表时删除授权。

GenerateDataKey

当您对表启用静态加密时,DynamoDB 会创建一个唯一表密钥。它将 GenerateDataKey 请求发送到指定表 KMS 密钥的 Amazon KMS 中。

记录 GenerateDataKey 操作的事件与以下示例事件类似。该用户是 DynamoDB 服务账户。参数包括 KMS 密钥的 Amazon Resource Name (ARN)、需要 256 位密钥的密钥说明符以及标识表和 Amazon Web Services 账户 的加密上下文

{ "eventVersion": "1.05", "userIdentity": { "type": "AWSService", "invokedBy": "dynamodb.amazonaws.com" }, "eventTime": "2018-02-14T00:15:17Z", "eventSource": "kms.amazonaws.com", "eventName": "GenerateDataKey", "awsRegion": "us-west-2", "sourceIPAddress": "dynamodb.amazonaws.com", "userAgent": "dynamodb.amazonaws.com", "requestParameters": { "encryptionContext": { "aws:dynamodb:tableName": "Services", "aws:dynamodb:subscriberId": "111122223333" }, "keySpec": "AES_256", "keyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" }, "responseElements": null, "requestID": "229386c1-111c-11e8-9e21-c11ed5a52190", "eventID": "e3c436e9-ebca-494e-9457-8123a1f5e979", "readOnly": true, "resources": [ { "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "accountId": "111122223333", "type": "AWS::KMS::Key" } ], "eventType": "AwsApiCall", "recipientAccountId": "111122223333", "sharedEventID": "bf915fa6-6ceb-4659-8912-e36b69846aad" }
Decrypt

当您访问加密的 DynamoDB 表时,DynamoDB 需要解密表密钥,以便它可以解密层次结构中位于其下方的密钥。然后,解密表中的数据。解密表密钥。DynamoDB 将 Decrypt 请求发送到指定表 KMS 密钥的 Amazon KMS 中。

记录 Decrypt 操作的事件与以下示例事件类似。用户是您的 Amazon Web Services 账户 中正在访问表的委托人。参数包括加密表密钥(作为密文 blob)以及标识表和 Amazon Web Services 账户 的加密上下文。Amazon KMS 从密文中得出 KMS 密钥 ID。

{ "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAIGDTESTANDEXAMPLE:user01", "arn": "arn:aws:sts::111122223333:assumed-role/Admin/user01", "accountId": "111122223333", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "sessionContext": { "attributes": { "mfaAuthenticated": "false", "creationDate": "2018-02-14T16:42:15Z" }, "sessionIssuer": { "type": "Role", "principalId": "AROAIGDT3HGFQZX4RY6RU", "arn": "arn:aws:iam::111122223333:role/Admin", "accountId": "111122223333", "userName": "Admin" } }, "invokedBy": "dynamodb.amazonaws.com" }, "eventTime": "2018-02-14T16:42:39Z", "eventSource": "kms.amazonaws.com", "eventName": "Decrypt", "awsRegion": "us-west-2", "sourceIPAddress": "dynamodb.amazonaws.com", "userAgent": "dynamodb.amazonaws.com", "requestParameters": { "encryptionContext": { "aws:dynamodb:tableName": "Books", "aws:dynamodb:subscriberId": "111122223333" } }, "responseElements": null, "requestID": "11cab293-11a6-11e8-8386-13160d3e5db5", "eventID": "b7d16574-e887-4b5b-a064-bf92f8ec9ad3", "readOnly": true, "resources": [ { "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "accountId": "111122223333", "type": "AWS::KMS::Key" } ], "eventType": "AwsApiCall", "recipientAccountId": "111122223333" }
CreateGrant

如果使用客户托管式密钥Amazon 托管式密钥 保护 DynamoDB 表,则 DynamoDB 会使用授权以允许服务执行持续数据保护和维护以及持久性任务。不需要这些授权。。Amazon 拥有的密钥

DynamoDB 创建的授权特定于表。CreateGrant 请求的委托人是创建了表的用户。

记录 CreateGrant 操作的事件与以下示例事件类似。参数包括表的 KMS 密钥的 Amazon Resource Name (ARN)、被授权委托人和停用委托人(DynamoDB 服务)以及授权涵盖的操作。它还包括要求所有加密操作都使用指定加密上下文的约束。

{ "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAIGDTESTANDEXAMPLE:user01", "arn": "arn:aws:sts::111122223333:assumed-role/Admin/user01", "accountId": "111122223333", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "sessionContext": { "attributes": { "mfaAuthenticated": "false", "creationDate": "2018-02-14T00:12:02Z" }, "sessionIssuer": { "type": "Role", "principalId": "AROAIGDTESTANDEXAMPLE", "arn": "arn:aws:iam::111122223333:role/Admin", "accountId": "111122223333", "userName": "Admin" } }, "invokedBy": "dynamodb.amazonaws.com" }, "eventTime": "2018-02-14T00:15:15Z", "eventSource": "kms.amazonaws.com", "eventName": "CreateGrant", "awsRegion": "us-west-2", "sourceIPAddress": "dynamodb.amazonaws.com", "userAgent": "dynamodb.amazonaws.com", "requestParameters": { "keyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "retiringPrincipal": "dynamodb.us-west-2.amazonaws.com", "constraints": { "encryptionContextSubset": { "aws:dynamodb:tableName": "Books", "aws:dynamodb:subscriberId": "111122223333" } }, "granteePrincipal": "dynamodb.us-west-2.amazonaws.com", "operations": [ "DescribeKey", "GenerateDataKey", "Decrypt", "Encrypt", "ReEncryptFrom", "ReEncryptTo", "RetireGrant" ] }, "responseElements": { "grantId": "5c5cd4a3d68e65e77795f5ccc2516dff057308172b0cd107c85b5215c6e48bde" }, "requestID": "2192b82a-111c-11e8-a528-f398979205d8", "eventID": "a03d65c3-9fee-4111-9816-8bf96b73df01", "readOnly": false, "resources": [ { "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "accountId": "111122223333", "type": "AWS::KMS::Key" } ], "eventType": "AwsApiCall", "recipientAccountId": "111122223333" }