

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

# 使用适用于 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) 在保存时清除和替换所有属性。