

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

# .NET
<a name="ddb-net"></a>

本主题介绍如何安装和使用版本 3。 DynamoDB 的.NET 客户端加密库中的 *x*。有关使用适用于 DynamoDB 的 AWS 数据库加密 SDK 进行编程的详细信息，请参阅上-dynamodb 存储库[中的 aws-database-encryption-sdk .NET](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/) 示例。 GitHub

DynamoDB 的.NET 客户端加密库适用于使用 C\$1 和其他.NET 编程语言编写应用程序的开发人员。它在 Windows、macOS 和 Linux 上受支持。

适用于 DynamoDB 的 AWS 数据库加密 SDK 的所有[编程语言](ddb-programming-languages.md)实现均可互操作。但是，列表或地图数据类型 适用于 .NET 的 SDK 不支持空值。这意味着，如果您使用适用于 DynamoDB 的 Java 客户端加密库来编写包含列表或地图数据类型的空值的项目，则无法使用适用于 DynamoDB 的.NET 客户端加密库来解密和读取该项目。

**Topics**
+ [安装](#ddb-net-install)
+ [调试](#ddb-net-debugging)
+ [使用.NET 客户端](ddb-net-using.md)
+ [.NET 示](ddb-net-examples.md)
+ [将版本 3.x 添加到现有表](ddb-net-config-existing-table.md)

## 为 DynamoDB 安装.NET 客户端加密库
<a name="ddb-net-install"></a>

[DynamoDB 的.NET 客户端加密库以 AWS.cryptography 的形式提供。 DbEncryptionSDK。 DynamoDb](https://www.nuget.org/packages/AWS.Cryptography.DbEncryptionSDK.DynamoDb/)打包进去 NuGet。有关安装和构建库的详细信息，请参阅-dynamodb 存储库中的 [.NET README.md](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/DynamoDbEncryption/runtimes/net/README.md) 文件。 aws-database-encryption-sdk即使您没有 AWS Key Management Service 使用 () 密钥，DynamoDB 适用于 .NET 的 SDK 的.NET 客户端加密库也需要。AWS KMS随 适用于 .NET 的 SDK NuGet 软件包一起安装。

版本 3。 DynamoDB 的.NET 客户端加密库中的 *x* 支持.NET 6.0 和.NET Framework net48 及更高版本。

## 使用.NET 调试
<a name="ddb-net-debugging"></a>

DynamoDB 的.NET 客户端加密库不会生成任何日志。DynamoDB 的.NET 客户端加密库中的异常会生成异常消息，但不会生成堆栈跟踪。

为了帮助您进行调试，请务必在 适用于 .NET 的 SDK中启用日志记录功能。中的日志和错误消息 适用于 .NET 的 SDK 可以帮助您区分在 DynamoDB 的.NET 客户端加密库中出现的 适用于 .NET 的 SDK 错误和 DynamoDB 的.NET 客户端加密库中出现的错误。有关 适用于 .NET 的 SDK 日志记录的帮助，请参阅[AWSLogging](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-config-other.html#config-setting-awslogging)《*适用于 .NET 的 AWS SDK 开发人员指南》*。（要查看该主题，请展开 **Open to view .NET Framework content** 部分。）

# 使用适用于 DynamoDB 的.NET 客户端加密库
<a name="ddb-net-using"></a>

本主题解释了版本 3 中的一些函数和辅助类。 DynamoDB 的.NET 客户端加密库中的 *x*。

有关使用适用于 DynamoDB 的.NET 客户端加密库进行编程的详细信息，请参阅上的-dynamodb 存储库中的 [ aws-database-encryption-sdk.NET](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/) 示例。 GitHub

**Topics**
+ [项目加密程序](#ddb-net-item-encryptors)
+ [属性操作](#ddb-net-attribute-actions)
+ [加密配置](#ddb-net-config-encrypt)
+ [更新项目](#ddb-net-update-items)

## 项目加密程序
<a name="ddb-net-item-encryptors"></a>

DynamoDB AWS 数据库加密 SDK 的核心是一个项目加密器。你可以使用版本 3。 DynamoDB 的.NET 客户端加密库中的 *x*，用于通过以下方式对您的 DynamoDB 表项目进行加密、签名、验证和解密。

**适用于 DynamoDB 的低级 AWS 数据库加密 SDK API**  
您可以使用[表加密配置](#ddb-net-config-encrypt)来构建 DynamoDB 客户端，该客户端会自动使用您的 DynamoDB 请求在客户端对项目进行加密和签名。`PutItem`您可以直接使用此客户端，也可以构造[文档模型](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-document)或[对象持久化模型](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-object-persistence)。  
[您必须使用适用于 DynamoDB API 的低级 AWS 数据库加密 SDK 才能使用可搜索的加密。](searchable-encryption.md)

**较低级别的 `DynamoDbItemEncryptor`**  
较低级别的 `DynamoDbItemEncryptor` 无需调用 DynamoDB 即可直接对您的表项目进行加密、签名或解密和验证。它不会发出 DynamoDB `PutItem` 或 `GetItem` 请求。举例来说，您可以使用较低级别的 `DynamoDbItemEncryptor` 直接解密和验证已经检索到的 DynamoDB 项目。如果您使用较低级别`DynamoDbItemEncryptor`，我们建议您使用[低级编程模型，该模型](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-low-level) 适用于 .NET 的 SDK 用于与 DynamoDB 通信。  
较低级别的 `DynamoDbItemEncryptor` 不支持[可搜索加密](searchable-encryption.md)。

## 适用于 DynamoDB 的 AWS 数据库加密 SDK 中的属性操作
<a name="ddb-net-attribute-actions"></a>

[属性操作](concepts.md#crypt-actions)决定哪些属性值经过加密和签名，哪些仅经过签名，哪些经过签名并包含在加密上下文中，哪些会被忽略。

要使用.NET 客户端指定属性操作，请使用对象模型手动定义属性操作。通过创建一个`Dictionary`对象来指定您的属性操作，其中名称-值对表示属性名称和指定操作。

指定 `ENCRYPT_AND_SIGN` 以对属性进行加密和签名。指定 `SIGN_ONLY` 以对属性进行签名，但不进行加密。指定`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`对属性进行签名并将其包含在加密上下文中。如果不对属性进行签名，也将无法对其进行加密。指定 `DO_NOTHING` 以忽略某个属性。

分区和排序属性必须为`SIGN_ONLY`或`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。如果将任何属性定义为`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`，则分区和排序属性也必须是`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

**注意**  
定义属性操作后，必须定义将哪些属性排除在签名之外。为了将来更方便添加新的未签名属性，建议您选择一个不同的前缀（例如“`:`”）来标识您的未签名属性。在定义 DynamoDB 架构和属性操作时，将此前缀包含在标记为 `DO_NOTHING` 的所有属性的属性名称中。

以下对象模型演示了如何使用.NET 客户端指定`ENCRYPT_AND_SIGN``SIGN_ONLY``SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`、、和`DO_NOTHING`属性操作。此示例使用前缀 “`:`” 来标识`DO_NOTHING`属性。

**注意**  
要使用`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`加密操作，必须使用 AWS 数据库加密 SDK 的 3.3 或更高版本。在[更新要包含的数据模型之前，先将](ddb-update-data-model.md)新版本部署给所有读者`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

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

## 适用于 DynamoDB 的 AWS 数据库加密 SDK 中的加密配置
<a name="ddb-net-config-encrypt"></a>

使用 AWS 数据库加密 SDK 时，必须为 DynamoDB 表显式定义加密配置。加密配置中所需的值取决于您是手动定义属性操作还是使用带注释的数据类来进行定义。

以下代码段使用适用于 DynamoDB API 的 AWS 低级数据库加密 SDK 定义了 DynamoDB 表加密配置，并允许使用不同前缀定义的未签名属性。

```
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: SearchConfig only required if you use beacons
    Search = new SearchConfig
    {
        WriteVersion = 1, // MUST be 1
        Versions = beaconVersions
    }    
};
tableConfigs.Add(ddbTableName, config);
```

**逻辑表名**  
适用于您的 DynamoDB 表的逻辑表名称。  
为简化 DynamoDB 还原操作，逻辑表名称以加密方式绑定到表中存储的所有数据。强烈建议您在首次定义加密配置时将 DynamoDB 表名指定为逻辑表名。必须始终指定相同的逻辑表名。要成功解密，逻辑表名称必须与加密时所指定的名称相匹配。如果您的 DynamoDB 表名称在[从备份中恢复 DynamoDB 表](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Restore.Tutorial.html)后发生更改，则逻辑表名称可确保解密操作仍能识别该表。

**允许的未签名属性**  
在您的属性操作中标记为 `DO_NOTHING` 的属性。  
允许的未签名属性将告诉客户端哪些属性被排除在签名之外。客户端假设，所有的其他属性都包含在签名中。然后，在解密记录时，客户端会从您指定的允许的未签名属性中确定需要验证哪些属性以及需要忽略哪些属性。您将不能从允许的未签名属性中移除属性。  
您可以通过创建一个列出所有 `DO_NOTHING` 属性的数组来显式定义允许的未签名属性。您还可以在命名 `DO_NOTHING` 属性时指定不同的前缀，并使用前缀告诉客户端哪些属性未签名。强烈建议指定一个不同的前缀，因为它可以简化未来添加新的 `DO_NOTHING` 属性的过程。有关更多信息，请参阅 [更新您的数据模型](ddb-update-data-model.md)。  
如果您没有为所有 `DO_NOTHING` 属性指定前缀，可以配置一个 `allowedUnsignedAttributes` 数组，该数组将显式列出客户端在解密时遇到这些属性时应该取消签名的所有属性。您只有在绝对必要时，才应显式定义允许的未签名属性。

**搜索配置（可选）**  
`SearchConfig` 将定义[信标版本](using-beacons.md#beacon-version)。  
必须指定 `SearchConfig` 才能使用[可搜索的加密](searchable-encryption.md)或[签名信标](configure.md#signed-beacons)。

**算法套件（可选）**  
`algorithmSuiteId` 定义 AWS 数据库加密 SDK 使用哪种算法套件。  
除非您明确指定替代算法套件，否则 AWS 数据库加密 SDK 将使用[默认算法套件](supported-algorithms.md#recommended-algorithms)。默认算法套件将 AES-GCM 算法与密钥派生、[数字签名](concepts.md#digital-sigs)和[密钥承诺](concepts.md#key-commitment)结合使用。尽管默认算法套件可能适用于大多数应用程序，但您可以选择备用算法套件。例如，没有数字签名的算法套件可以满足某些信任模型的需求。有关 AWS 数据库加密 SDK 支持的算法套件的信息，请参阅[AWS 数据库加密 SDK 中支持的算法套件](supported-algorithms.md)。  
要选择[没有 ECDSA 数字签名的 AES-GCM 算法套件](supported-algorithms.md#other-algorithms)，请在表加密配置中加入以下片段。  

```
AlgorithmSuiteId = DBEAlgorithmSuiteId.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_SYMSIG_HMAC_SHA384
```

## 使用 AWS 数据库加密 SDK 更新项目
<a name="ddb-net-update-items"></a>

UpdateItem对于包含加密或签名属性的项目，[数据库加密 SDK 不支持 ddb:](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)。 AWS 要更新加密或已签名的属性，必须使用 [ddb: PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)。如果将同一个主键指定为 `PutItem` 请求中现有的项目，则新项目将完全替代现有项目。更新项目后，您还可以使用 [CLOBBER](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.SaveBehavior.html#CLOBBER) 在保存时清除和替换所有属性。

# .NET 示
<a name="ddb-net-examples"></a>

以下示例向您展示如何使用适用于 DynamoDB 的.NET 客户端加密库来保护应用程序中的表项目。要查找更多示例（并贡献自己的示例），请参阅上的 aws-database-encryption-sdk-dy [namodb 存储库中的.NET 示例](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/net/src)。 GitHub

以下示例演示了如何在未填充的全新 Amazon DynamoDB 表中为 DynamoDB 配置.NET 客户端加密库。如果您想配置现有的 Amazon DynamoDB 表以进行客户端加密，请参阅 [将版本 3.x 添加到现有表](ddb-net-config-existing-table.md)。

**Topics**
+ [使用适用于 DynamoDB 的低级 AWS 数据库加密 SDK API](#ddb-net-lowlevel-API-example)
+ [使用较低的级别 `DynamoDbItemEncryptor`](#ddb-net-itemencryptor)

## 使用适用于 DynamoDB 的低级 AWS 数据库加密 SDK API
<a name="ddb-net-lowlevel-API-example"></a>

[以下示例说明如何使用适用于 DynamoDB 的低级 AWS 数据库加密 SDK API 和密钥环，通过AWS KMS 您的 DynamoDB 请求在客户端自动加密和签名项目。](use-kms-keyring.md) `PutItem`

您可以使用任何支持的[密钥环](keyrings.md)，但我们建议尽可能使用其中一个 AWS KMS 密钥环。

**查看完整的代码示例**：[BasicPutGetExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/BasicPutGetExample.cs)

**步骤 1：创建 AWS KMS 密钥环**  
以下示例使用`CreateAwsKmsMrkMultiKeyring`对称加密 KMS AWS KMS 密钥创建密钥环。`CreateAwsKmsMrkMultiKeyring` 方法可确保密钥环能够正确处理单区域密钥和多区域密钥。  

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

**步骤 2：配置属性操作**  
以下示例定义了一个`attributeActionsOnEncrypt`字典，该字典表示表格项目的示例[属性操作](concepts.md#crypt-actions)。  
以下示例未将任何属性定义为`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。如果您指定了任何`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
};
```

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

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

**步骤 4：定义 DynamoDB 表的加密配置**  
以下示例定义了一个 `tableConfigs` 映射，该映射表示此 DynamoDB 表的加密配置。  
此示例将 DynamoDB 表名称指定为[逻辑表名称](ddb-net-using.md#net-logical-table-name)。强烈建议您在首次定义加密配置时将 DynamoDB 表名指定为逻辑表名。有关更多信息，请参阅 [适用于 DynamoDB 的 AWS 数据库加密 SDK 中的加密配置](ddb-net-using.md#ddb-net-config-encrypt)。  
要使用[可搜索的加密](searchable-encryption.md)或[签名信标](configure.md#signed-beacons)，您还必须在加密配置中包括 [`SearchConfig`](ddb-java-using.md#ddb-search-config)。

```
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
};
tableConfigs.Add(ddbTableName, config);
```

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

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

**步骤 6：对 DynamoDB 表格项目进行加密和签名**  
以下示例定义了一个代表示例表项目的`item`字典，并将该项目放入 DynamoDB 表中。该项目在发送到 DynamoDB 之前将在客户端进行加密和签名。  

```
var item = new Dictionary<String, AttributeValue>
{
    ["partition_key"] = new AttributeValue("BasicPutGetExample"),
    ["sort_key"] = new AttributeValue { N = "0" },
    ["attribute1"] = new AttributeValue("encrypt and sign me!"),
    ["attribute2"] = new AttributeValue("sign me!"),
    [":attribute3"] = new AttributeValue("ignore me!")
};

PutItemRequest putRequest = new PutItemRequest
{
    TableName = ddbTableName,
    Item = item
};

PutItemResponse putResponse = await ddb.PutItemAsync(putRequest);
```

## 使用较低的级别 `DynamoDbItemEncryptor`
<a name="ddb-net-itemencryptor"></a>

以下示例说明如何使用带有 [AWS KMS 密钥环](use-kms-keyring.md)的较低级别 `DynamoDbItemEncryptor` 来直接对表项目进行加密和签名。`DynamoDbItemEncryptor` 不会将项目放入 DynamoDB 表中。

您可以在 DynamoDB 增强版客户端中使用任何支持的[密钥环](keyrings.md)，但我们建议尽可能使用其中 AWS KMS 一个密钥环。

**注意**  
较低级别的 `DynamoDbItemEncryptor` 不支持[可搜索加密](searchable-encryption.md)。使用适用于 DynamoDB 的低级 AWS 数据库加密 SDK API 来使用可搜索的加密。

**查看完整的代码示例**：[ItemEncryptDecryptExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/itemencryptor/ItemEncryptDecryptExample.cs)

**步骤 1：创建 AWS KMS 密钥环**  
以下示例使用`CreateAwsKmsMrkMultiKeyring`对称加密 KMS AWS KMS 密钥创建密钥环。`CreateAwsKmsMrkMultiKeyring` 方法可确保密钥环能够正确处理单区域密钥和多区域密钥。  

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

**步骤 2：配置属性操作**  
以下示例定义了一个`attributeActionsOnEncrypt`字典，该字典表示表格项目的示例[属性操作](concepts.md#crypt-actions)。  
以下示例未将任何属性定义为`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。如果您指定了任何`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
};
```

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

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

**步骤 4：定义 `DynamoDbItemEncryptor` 配置**  
以下示例定义 `DynamoDbItemEncryptor` 的配置。  
此示例将 DynamoDB 表名称指定为[逻辑表名称](ddb-net-using.md#net-logical-table-name)。强烈建议您在首次定义加密配置时将 DynamoDB 表名指定为逻辑表名。有关更多信息，请参阅 [适用于 DynamoDB 的 AWS 数据库加密 SDK 中的加密配置](ddb-net-using.md#ddb-net-config-encrypt)。  

```
var config = new DynamoDbItemEncryptorConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix
};
```

**步骤 5：创建 `DynamoDbItemEncryptor`**  
以下示例使用**步骤 4** 中的 `config` 创建新的 `DynamoDbItemEncryptor`。  

```
var itemEncryptor = new DynamoDbItemEncryptor(config);
```

**步骤 6：直接对表项目进行加密和签名**  
以下示例使用 `DynamoDbItemEncryptor` 直接对项目进行加密和签名。`DynamoDbItemEncryptor` 不会将项目放入 DynamoDB 表中。  

```
var originalItem = new Dictionary<String, AttributeValue>
{
    ["partition_key"] = new AttributeValue("ItemEncryptDecryptExample"),
    ["sort_key"] = new AttributeValue { N = "0" },
    ["attribute1"] = new AttributeValue("encrypt and sign me!"),
    ["attribute2"] = new AttributeValue("sign me!"),
    [":attribute3"] = new AttributeValue("ignore me!")
};

var encryptedItem = itemEncryptor.EncryptItem(
    new EncryptItemInput { PlaintextItem = originalItem }
).EncryptedItem;
```

# 将现有 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);
```