

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将现有 DynamoDB 表配置为使用适用于 DynamoDB AWS 的数据库加密 SDK
<a name="ddb-net-config-existing-table"></a>

使用版本 3。 *x* 在 DynamoDB 的.NET 客户端加密库中，您可以将现有的 Amazon DynamoDB 表配置为用于客户端加密。本主题提供有关添加版本 3.*x* 到已填充的现有 DynamoDB 表要采取的三个步骤的指导。

## 步骤 1：准备读取和写入加密项目
<a name="ddb-net-add-step1"></a>

完成以下步骤，为 AWS 数据库加密 SDK 客户端做好读取和写入加密项目的准备。部署以下更改后，您的客户端将继续读取和写入明文项目。它不会对写入表中的任何新项目进行加密或签名，但却能够在加密项目显示后立即对其进行解密。这些更改使得客户端为开始[加密新项目](#ddb-net-add-step2)做好准备。在继续执行下一步操作之前，必须将以下更改部署到每一个读取器。

**1. 定义您的[属性操作](concepts.md#crypt-actions)**  
创建对象模型以定义哪些属性值将进行加密和签名，哪些仅进行签名，哪些将被忽略。  
默认情况下，主键属性已签名但未加密（`SIGN_ONLY`），而所有其他属性均经过加密和签名（`ENCRYPT_AND_SIGN`）。  
指定 `ENCRYPT_AND_SIGN` 以对属性进行加密和签名。指定 `SIGN_ONLY` 以对属性进行签名，但不进行加密。指定`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`要签名并归因并将其包含在加密上下文中。如果不对属性进行签名，也将无法对其进行加密。指定 `DO_NOTHING` 以忽略某个属性。有关更多信息，请参阅 [适用于 DynamoDB 的 AWS 数据库加密 SDK 中的属性操作](ddb-net-using.md#ddb-net-attribute-actions)。  
如果您指定了任何`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`属性，则分区和排序属性也必须是`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

```
var attributeActionsOnEncrypt = new Dictionary<string, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_ONLY, // The partition attribute must be SIGN_ONLY
    ["sort_key"] = CryptoAction.SIGN_ONLY, // The sort attribute must be SIGN_ONLY
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    [":attribute3"] = CryptoAction.DO_NOTHING
};
```

**2. 定义从签名中将可以排除哪些属性**  
以下示例假设所有 `DO_NOTHING` 属性共享不同的前缀“`:`”，并使用该前缀定义允许的未签名属性。客户端将假设任何带有“`:`”前缀的属性名称都被排除在签名之外。有关更多信息，请参阅 [Allowed unsigned attributes](ddb-net-using.md#net-allowed-unauth)。  

```
const String unsignAttrPrefix = ":";
```

**3. 创建[密钥环](keyrings.md)**  
以下示例创建一个 [AWS KMS 密钥环](use-kms-keyring.md)。 AWS KMS 密钥环使用对称加密或非对称 RSA AWS KMS keys 来生成、加密和解密数据密钥。  
该示例使用 `CreateMrkMultiKeyring` 创建带有对称加密 KMS 密钥的 AWS KMS 密钥环。`CreateAwsKmsMrkMultiKeyring` 方法可确保密钥环能够正确处理单区域密钥和多区域密钥。  

```
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId };
var kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**4. 定义 DynamoDB 表的加密配置 **  
以下示例定义了一个 `tableConfigs` 映射，该映射表示此 DynamoDB 表的加密配置。  
此示例将 DynamoDB 表名称指定为[逻辑表名称](ddb-net-using.md#net-logical-table-name)。强烈建议您在首次定义加密配置时将 DynamoDB 表名指定为逻辑表名。  
必须指定 `FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT` 作为明文替代。此策略继续读取和写入明文项目，读取加密项目，并使客户端做好准备以写入加密项目。  
有关表加密配置中包含的值的更多信息，请参阅[适用于 DynamoDB 的 AWS 数据库加密 SDK 中的加密配置](ddb-java-using.md#ddb-config-encrypt)。  

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    PlaintextOverride = FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```

**5. 创建新的 AWS SDK DynamoDB 客户端**  
**以下示例使用步骤 4 中的创建了一个新 AWS 的 SDK DynamoDB 客户端`TableEncryptionConfigs`。**  

```
var ddb = new Client.DynamoDbClient(
    new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs });
```

## 步骤 2：写入已加密和签名项目
<a name="ddb-net-add-step2"></a>

更新表加密配置中的明文策略，以允许客户端写入加密和签名的项目。部署好以下更改后，客户端将根据您在**步骤 1** 中配置的属性操作对新项目进行加密和签名。客户将能够读取明文项目以及已加密和签名的项目。

在继续执行[步骤 3](#ddb-net-add-step3) 之前，您必须对表格中所有现有的明文项目进行加密和签名。您无法运行单一指标或查询来快速加密您的现有明文项目。使用对您的系统最有意义的过程。例如，您可以使用异步过程，以缓慢扫描表，然后使用您定义的属性操作和加密配置重写项目。要识别表中的纯文本项目，我们建议您扫描所有不包含 AWS 数据库加密 SDK 在项目加密`aws_dbe_head`和签名时添加的和`aws_dbe_foot`属性的项目。

以下示例更新了**步骤 1** 中的表加密配置。您必须使用 `FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT` 更新明文替代。该策略继续读取明文项目，但也会读取和写入加密项目。使用更新后的 AWS DynamoDB 客户端创建一个新的 SDK DynamoDB 客户端。`TableEncryptionConfigs`

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    PlaintextOverride = FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```

## 步骤 3：仅读取已加密和签名项目
<a name="ddb-net-add-step3"></a>

对所有项目进行加密和签名后，请更新表加密配置中的明文替代，使其仅允许客户端读取和写入加密和签名的项目。部署好以下更改后，客户端将根据您在**步骤 1** 中配置的属性操作对新项目进行加密和签名。客户只能够读取已加密和签名的项目。

以下示例更新了**步骤 2** 中的表加密配置。您可以使用 `FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT` 更新明文替代，也可以从配置中移除明文策略。默认情况下，客户端仅读取和写入已加密和签名的项目。使用更新后的 AWS DynamoDB 客户端创建一个新的 SDK DynamoDB 客户端。`TableEncryptionConfigs`

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    // Optional: you can also remove the plaintext policy from your configuration
    PlaintextOverride = FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```