

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

# 多租户数据库的可搜索加密
<a name="searchable-encryption-multitenant"></a>


****  

|  | 
| --- |
| 我们的客户端加密库已重命名为 AWS 数据库加密 SDK。本开发人员指南仍提供有关 [DynamoDB 加密客户端](legacy-dynamodb-encryption-client.md)的信息。 | 

要在数据库中实现可搜索的加密，必须使用 [AWS KMS 分层密钥环](use-hierarchical-keyring.md)。分 AWS KMS 层密钥环生成、加密和解密用于保护记录的数据密钥。它还创建用于生成信标的信标密钥。在多租户数据库中使用 AWS KMS 分层密钥环时，每个租户都有不同的分支密钥和信标密钥。要查询多租户数据库中的加密数据，必须确定用于生成所查询信标的信标密钥材料。有关更多信息，请参阅 [使用分层密钥环进行可搜索加密](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings)。

在为多租户数据库定义[信标版本](using-beacons.md#beacon-version)时，请指定您配置的所有标准信标的列表、您配置的所有复合信标的列表、信标版本和 `keySource`。您必须[将信标密钥源定义](use-hierarchical-keyring.md#beacon-key-source)为 `MultiKeyStore`，并包括 `keyFieldName`、一个本地信标密钥缓存的缓存生存时间和本地信标密钥缓存的最大缓存大小。

如果您已配置任何[已签名的信标](configure.md#signed-beacons)，则必须将其包含在您的 `compoundBeaconList` 中。签名信标是一种复合信标，用于对和`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`字段进行索引`SIGN_ONLY`和执行复杂查询。

------
#### [ Java ]

```
List<BeaconVersion> beaconVersions = new ArrayList<>();
    beaconVersions.add(
        BeaconVersion.builder()
                .standardBeacons(standardBeaconList)
                .compoundBeacons(compoundBeaconList)
                .version(1) // MUST be 1
                .keyStore(branchKeyStoreName)
                .keySource(BeaconKeySource.builder()
                        .multi(MultiKeyStore.builder()
                                .keyFieldName(keyField)
                                .cacheTTL(6000)
                                .maxCacheSize(10)
                        .build())
                .build())
        .build()
    );
```

------
#### [ C\$1 / .NET ]

```
var beaconVersions = new List<BeaconVersion>
{
    new BeaconVersion
    {
        StandardBeacons = standardBeaconList,
        CompoundBeacons = compoundBeaconList,
        EncryptedParts = encryptedPartsList,
        SignedParts = signedPartsList,
        Version = 1, // MUST be 1
        KeyStore = branchKeyStoreName,
        KeySource = new BeaconKeySource
        {
            Multi = new MultiKeyStore
            {
                KeyId = branch-key-id,
                CacheTTL = 6000,
                MaxCacheSize = 10
            }
        }
    }
};
```

------
#### [ Rust ]

```
let beacon_version = BeaconVersion::builder()
    .standard_beacons(standard_beacon_list)
    .compound_beacons(compound_beacon_list)
    .version(1) // MUST be 1
    .key_store(key_store.clone())
    .key_source(BeaconKeySource::Multi(
        MultiKeyStore::builder()
            // `keyId` references a beacon key.
            // For every branch key we create in the keystore,
            // we also create a beacon key.
            // This beacon key is not the same as the branch key,
            // but is created with the same ID as the branch key.
            .key_id(branch_key_id)
            .cache_ttl(6000)
            .max_cache_size(10)
            .build()?,
    ))
    .build()?;
let beacon_versions = vec![beacon_version];
```

------

**keyFieldName**  
[`keyFieldName`](use-hierarchical-keyring.md#keyFieldName) 定义存储与信标密钥关联的 `branch-key-id` 的字段名称，该信标密钥用于为给定租户生成信标。  
当您将新记录写入数据库时，标识用于为该记录生成任何信标的信标密钥的 `branch-key-id` 将存储在此字段中。  
默认情况下，`keyField` 是不显式存储在数据库中的概念字段。Dat AWS abase Encryption SDK `branch-key-id` 从[材料描述](concepts.md#material-description)中的加密[数据密钥](concepts.md#data-key)中识别出来，并将该值存储在概念中，`keyField`供您在复合信标和[签名信](configure.md#signed-beacons)标中引用。由于材料描述已签名，因此概念 `keyField` 被视为已签名的部分。  
您也可以将作为`SIGN_ONLY`或`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`字段包含`keyField`在加密操作中，以将该字段显式存储在数据库中。如果这样做，则当您每次向数据库写入记录时都必须将 `branch-key-id` 手动包含在 `keyField` 中。

## 查询多租户数据库中的信标
<a name="query-multitenant-beacons"></a>

要查询信标，您必须在查询中包含 `keyField`，以确定重新计算信标所需的相应信标密钥材料。必须指定与用于生成记录信标的信标密钥关联的 `branch-key-id`。您不能在分支密钥 ID 供应程序中指定用于标识租户的 `branch-key-id` 的[易记名称](use-hierarchical-keyring.md#branch-key-id-supplier)。您可以通过以下方式将 `keyField` 包含在查询中。

**复合信标**  
无论您是否明确将 `keyField` 存储在记录中，您都可以将 `keyField` 作为签名部分直接包含在复合信标中。`keyField` 签名部分必须为必填项。  
例如，如果要从两个字段 `encryptedField` 和 `signedField` 中构造复合信标 `compoundBeacon`，则还必须将 `keyField` 作为签名部分包含在内。这使您能够对 `compoundBeacon` 执行以下查询。  

```
compoundBeacon = E_encryptedFieldValue.S_signedFieldValue.K_branch-key-id
```

**签名信标**  
 AWS 数据库加密 SDK 使用标准信标和复合信标来提供可搜索的加密解决方案。这些信标必须至少包括一个加密字段。但是， AWS 数据库加密 SDK 还支持[签名信标](configure.md#signed-beacons)，这些信标可以完全通过纯文本`SIGN_ONLY`和字段进行配置。`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`  
签名信标可以由单个部分构造。无论您是否明确将 `keyField` 存储在记录中，您都可以从 `keyField` 中构造签名信标，并使用它来创建复合查询，该查询将对 `keyField` 签名信标的查询与对其他信标的查询组合在一起。例如，您可以执行以下查询。  

```
keyField = K_branch-key-id AND compoundBeacon = E_encryptedFieldValue.S_signedFieldValue
```
如需帮助配置签名信标，请参阅 [创建签名的信标](configure.md#signed-beacons)

**直接在 `keyField` 上查询**  
如果您在加密操作中指定了 `keyField` 并将该字段显式存储在记录中，则可以创建一个复合查询，该查询将对信标的查询与对 `keyField` 的查询组合在一起。如果要查询标准信标，可以选择直接在 `keyField` 上查询。例如，您可以执行以下查询。  

```
keyField = branch-key-id AND standardBeacon = S_standardBeaconValue
```