DynamoDB 静态加密使用注意事项 - Amazon DynamoDB

DynamoDB 静态加密使用注意事项

在 Amazon DynamoDB 中使用静态加密时,请注意以下事项。

所有表数据已加密

所有 DynamoDB 表数据已启用服务器端静态加密,无法禁用。无法仅加密表的项目子集。

静态加密仅加密持久存储介质上的静态数据。如果正在传输的数据或正在使用的数据担心数据安全,则可能需要采取额外措施:

  • 传输中数据:DynamoDB 中的所有数据在传输过程中都会加密。默认情况下,与 DynamoDB 的通信将使用 HTTPS 协议,通过安全套接字层 (SSL)/传输层安全性 (TLS) 加密保护网络流量。

  • 正在使用的数据:在将数据发送到 DynamoDB 之前,使用客户端加密保护数据。有关更多信息,请参阅《Amazon DynamoDB Encryption Client 开发人员指南》中的客户端和服务器端加密

可以将流与加密表一起使用。DynamoDB 流始终使用表级加密密钥进行加密。有关更多信息,请参阅 将更改数据捕获用于 DynamoDB Streams

DynamoDB 备份已加密,从备份还原的表也启用加密。可以使用 AWS 拥有的密钥、AWS 托管式密钥 或客户托管密钥加密备份数据。有关更多信息,请参阅 DynamoDB 的备份和还原

使用与基表相同的密钥加密本地二级索引和全局二级索引。

加密类型

注意

全局表版本 2017 中不支持客户管理的密钥。如果您要在 DynamoDB 全局表中使用客户管理的密钥,则需要将表升级到全局表版本 2019,然后启用它。

在 AWS Management Console,如果使用 AWS 托管式密钥 或客户托管密钥加密数据,加密类型为 KMS。如果使用 AWS 拥有的密钥,加密类型为 DEFAULT。在 Amazon DynamoDB API 中,如果使用 AWS 托管式密钥 或客户托管密钥,加密类型为 KMS。如果没有加密类型,将使用 AWS 拥有的密钥 加密数据。可以随时在 AWS 拥有的密钥、AWS 托管式密钥 和客户托管密钥之间切换。可以使用控制台、AWS Command Line Interface (AWS CLI) 或 Amazon DynamoDB API 切换加密密钥。

使用客户托管密钥时,请注意以下限制:

  • 不能将客户托管密钥与 DynamoDB Accelerator (DAX) 集群一起使用。有关更多信息,请参阅 DAX 静态加密

  • 可以使用客户托管密钥加密使用事务处理的表。但是,为了确保事务传播的持久性,服务会临时存储事务请求的副本,并使用 AWS 拥有的密钥 加密。始终使用客户托管密钥静态加密表和二级索引中的已提交数据。

  • 可以使用客户托管密钥加密使用 Contributor Insights 的表。但是,传输到 Amazon CloudWatch 的数据将使用 AWS 拥有的密钥 加密。

  • 当您转移到新的客户托管密钥时,请务必在流程完成之前保持原始密钥的启用状态。在使用新密钥加密之前,AWS 仍然需要原始密钥来解密数据。当表的 SSEDescription 状态为“已启用”并显示新客户托管密钥的 KMSMasterKeyArn 时,该过程将完成。此时,可以禁用原始密钥或计划删除。

  • 显示新的客户托管密钥后,表和任何新的按需备份都将使用新密钥加密。

  • 任何现有的按需备份都将使用创建这些备份时的客户托管密钥进行加密。需要同样的密钥才能还原这些备份。您可以使用 describeBackup API 查看该备份的 SSEDescription,以识别每个备份创建时期的密钥。

  • 如果禁用客户托管密钥或计划删除,则 DynamoDB Streams 中的任何数据仍然受 24 小时生命周期限制。24 小时以后,任何未检索的活动数据都可删除。

  • 如果禁用客户托管密钥或计划删除,生存时间(TTL)删除将继续 30 分钟。这些 TTL 删除将继续发送到 DynamoDB Streams,并受标准删除/保留间隔的约束。

    有关更多信息,请参阅 启用密钥删除密钥

使用 KMS 密钥和数据密钥

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

建议您在 DynamoDB 中实施表之前先制定加密策略计划。如果您要在 DynamoDB 中存储敏感或机密数据,请考虑在计划中包括客户端加密。这样,您就可以尽量靠近数据源来加密数据,确保其在整个生命周期中受到保护。有关更多信息,请参阅 DynamoDB 加密客户端文档。

AWS KMS key

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

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

重要

DynamoDB 仅支持对称 KMS 密钥。不能使用非对称 KMS 密钥来加密您的 DynamoDB 表。

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

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

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

表密钥

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

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

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

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

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

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

表密钥缓存

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

授权使用 KMS 密钥

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

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

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

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

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

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

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

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

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

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

{ "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 要求权限独立于任何特定 AWS 区域,以便它可以进行跨区域调用来支持 DynamoDB 全局表

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

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

{ "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 的客户托管式密钥或 AWS 托管式密钥 的权限 (aws/dynamodb)。要查看有关您账户中的 KMS 密钥的授权,请使用 ListGrants 操作。DynamoDB 不需要授权或任何其他权限即可使用 AWS 拥有的密钥 来保护您的表。

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

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

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

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

DynamoDB 加密上下文

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

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

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

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

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

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

    例如:

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

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

    例如:

    "aws:dynamodb:subscriberId": "111122223333"

监控 DynamoDB 与 AWS KMS 的交互

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

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

GenerateDataKey

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

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

{ "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": "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 密钥的 AWS KMS 中。

记录 Decrypt 操作的事件与以下示例事件类似。用户是您的 AWS 账户 中正在访问表的委托人。参数包括加密表密钥(作为密文 blob)以及标识表和 AWS 账户 的加密上下文。AWS 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

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

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

记录 CreateGrant 操作的事件与以下示例事件类似。参数包括表的 KMS 密钥的 Amazon 资源名称(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": "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" }