

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

# 选择信标长度和分区
<a name="choosing-beacon-length"></a>



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

当您向配置为可搜索加密的加密字段写入新值时， AWS 数据库加密 SDK 会根据与分区标识符组合的纯文本值计算 HMAC。在给定分区中，完整的 HMAC 唯一表示纯文本值。然后，SDK 会截断 HMAC 输出，以便多个不同的纯文本值可以映射到同一个信标。这些冲突（也称为*误报*）限制了未经授权的用户推断出有关底层纯文本的区分信息的能力。

为每个信标生成的平均误报数由截断后剩余的信标长度和正在使用的分区数量决定。配置标准信标时，只需要定义信标长度。复合信标使用构造它们的标准信标的信标长度。通过在多个分区之间分配值，可以在每个分区内保持冲突，这有助于降低频率集中度，同时保持正确的查询行为。

信标不会更改字段的加密状态。但是，当您使用信标时，查询的效率和泄露的有关数据分布的信息量之间存在内在权衡。更短的信标长度和额外的分区会增加碰撞并减少频率泄漏，而更长的信标长度和更少的分区可以提高查询精度。

可搜索加密的目标在于，使用信标对加密数据执行查询，从而降低与客户端加密数据库相关的性能成本。信标与计算信标所依据的加密字段一同存储。这意味着，它们可以揭示有关您的数据集分布的区别信息。在极端情况下，未经授权的用户可能能够分析披露的有关您的分布的信息，并用它来识别字段的明文值。选择适当的信标长度和分区计数有助于降低这些风险并保护数据的机密性。

查看您的威胁模型，以确定所需的安全级别。例如，有权访问您的数据库但不应访问明文数据的人越多，您就越想保护数据集分布的机密性。提高机密性通常需要生成更多的误报（通过缩短信标长度、增加分区或两者兼而有之），这反过来又会降低查询性能。

**Topics**
+ [选择分区方案](#choosing-partitioning-scheme)
+ [计算信标长度](#calculate-beacon-length)
+ [高级信标长度示例](#beacon-length-example)

## 选择分区方案
<a name="choosing-partitioning-scheme"></a>

 分区方案决定了派生信标时项目在分区之间的分布方式。选择合适的方案对于平衡隐私、性能和运营可预测性非常重要。

选择分区方案时，请考虑以下目标：
+  分配高频值以减少大型信标等效类别。
+  避免引入可能泄露敏感信息的可预测模式。
+  在写入和查询之间保持稳定的行为。

### 默认随机分布
<a name="w2aac15c25c29c17b9"></a>

 推荐的默认值是随机分布方案。在此模型中，使用加密安全的随机值将每个项目分配给一个分区。随机分布会随着时间的推移产生大致相等的分区大小，并确保频繁值的分布均匀。

在以下情况下使用随机分布：
+  您对价值分布没有很强的领域了解。
+  数据集包含未知或不断演变的偏差。
+  您想最大限度地减少与属性相关的泄漏。

### 确定性分布
<a name="w2aac15c25c29c17c11"></a>

 在某些情况下，分区分配必须是确定性的。确定性方案根据项目属性的稳定函数来分配分区。这些方案必须谨慎设计，因为偏斜或敏感的输入可能会导致分区不均匀或意想不到的信息泄露。

在以下情况下使用确定性分布：
+  操作工作流程取决于一致的分区放置。
+  您有一组特意分组为单个分区的唯一值。

### 处理已知的热门值
<a name="w2aac15c25c29c17c13"></a>

 如果您的数据集包含众所周知的热门值，则可以将随机策略和确定性策略结合起来。例如，您可以随机分配一小组高频值，同时确定性地分配所有其他值。

 这种方法降低了热值的集中度，同时保留了数据集其余部分的可预测行为。由于它会带来额外的复杂性，因此请仔细检查以避免意外的信息泄露。

### 分区方案示例
<a name="w2aac15c25c29c17c15"></a>

 以下示例说明了常见的分区方案，并显示了不同的数据特征如何影响分区分配。每个示例都演示了如何在隐私、性能和操作简单性之间取得平衡。

#### 示例 1：均匀分布的数据
<a name="w2aac15c25c29c17c15b5"></a>

 您正在为电话号码创建信标，并且数据集中的值几乎是均匀分布的。没有哪个电话号码出现的频率比其他电话号码高得多。

 在这种情况下，配置单个分区就足够了。额外的分区几乎没有什么好处，只会增加查询扇出。

#### 示例 2：频率偏差的二进制结果
<a name="w2aac15c25c29c17c15b7"></a>

 您有一个存储医学检查结果的数据库，其中包含两个可能的值：阴性和阳性。阴性结果出现的频率大约是阳性结果的五倍。

 要减少频率泄漏，请使用混合策略：
+  在五个分区中随机分配负数结果。
+  确定性地将阳性结果分配给单个分区。

 这种方法在保持稀有值稳定的同时分散被高表示的价值，从而减少了较大的等价类别，而不会出现不必要的扇出。

#### 示例 3：大型域名中的已知热门值
<a name="w2aac15c25c29c17c15b9"></a>

 你有一个美国名字数据库。相对较少的一组常用名（例如，最常见的500个名字）的出现频率远高于其他名称。
+  在四个分区中随机分配前 500 个最常用的名称。
+  确定性地将所有剩余名称分配给单个分区。
+  逐渐增加分区的数量，直到分配给每个分区的数据呈现出近乎均匀的分布。

 这种混合方法针对已知的热门值，同时保持大多数名称的分区简单且可预测。

 这些示例说明了如何使分区方案适应不同的数据特征。在大多数情况下，随机分布就足够了，但是如果谨慎使用，整合领域知识可以进一步改善隐私和性能。

## 计算信标长度
<a name="calculate-beacon-length"></a>

信标长度以比特为单位指定，它决定了截断后保留的 HMAC 输出中有多少位。建议的长度取决于值在每个分区内的分布方式、数据是否包含相关值以及您的安全和性能要求。当应用适当的分区方案后数据集大致一致时，您可以使用简单的方程和调整程序来估计有效的信标长度。这些方程提供了信标可能产生的平均误报数量的估计值，但它们并不能保证数据集中每个唯一值都有特定数量的误报。第一步是估算人口。

**注意**  
这些方程的有效性取决于数据集在每个分区中的分布。如果您的数据集分布不均匀，请参阅 [信标是否适合我的数据集？](searchable-encryption.md#are-beacons-right-for-me)。

### 估算总量
<a name="estimate-population"></a>

总量是指构造标准信标所依据的字段中的唯一值的预期数量，而不是字段中存储的值的预期总数。例如，考虑一个用于标识员工会议地点的加密 `Room` 字段。`Room` 字段预计将存储 100000 个总值，但员工只能预留 50 个不同的会议室用于会议。这意味着总量为 50，因为 `Room` 字段中只能存储 50 个可能的唯一值。

**注意**  
如果您的标准信标由[虚拟字段](beacons.md#virtual-field)构造，则用于计算信标长度的总量是虚拟字段创建的唯一组合数。

在估算总量时，请务必考虑数据集的预计增长。使用信标写入新记录后，您将无法更新信标长度。查看您的威胁模型和任何现有的数据库解决方案，以估算您预计该字段在未来五年内将存储的唯一值的数量。

您的总量不需要很精确。首先，确定当前数据库中唯一值的数量，或者估算第一年预计存储的唯一值的数量。接下来，通过以下问题来帮助您确定未来五年内唯一值的预计增长情况。
+ 您是否期望唯一值乘以 10？ 
+ 您是否期望唯一值乘以 100？ 
+ 您是否期望唯一值乘以 1000？ 

50000 和 60000 个唯一值之间的差异并不显著，两者都将产生相同的建议信标长度。但是，50000 和 500000 个唯一值之间的差异将显著影响建议的信标长度。

考虑查看常见数据类型（例如邮政编码或姓氏）出现频率的相关公共数据。举例来说，美国有 41707 个邮政编码。您使用的总量应与您自己的数据库成正比。如果数据库中的 `ZIPCode` 字段包含来自整个美国的数据，则即使 `ZIPCode` 字段*当前*没有 41707 个唯一值，也可以将总量定义为 41707。如果数据库中的 `ZIPCode` 字段仅包含来自单个州的数据，并且到目前为止仅包含来自单一州的数据，则可以将总量定义为该州的邮政编码总数，而不是 41704 个。

### 根据种群规模计算信标长度
<a name="calculating-beacon-length"></a>

 当您的数据在每个分区内大致均匀分布且不包含相关值时，您可以使用基于总量的简单公式来估计适当的信标长度。

 假*设 p* 是信标的种群大小，也就是说，信标在单个分区内构造的不同纯文本值的数量。信标长度 *b*（以位为单位）的常见起点是：

```
b = log₂(p) − 1
```

 该公式保留了不可忽视的碰撞概率，同时保持了误报数量的可控性。从对数中减去一个位可以确保将多个不同的值映射到同一个信标，这有助于限制频率泄漏并支持匿名性。

 此计算提供了对整个数据集的平均碰撞行为的估计值。它不能保证每个值都会产生相同数量的误报，也不能考虑偏斜的分布、相关值或对抗性数据模式。

 使用此公式作为初始指导方针，而不是严格要求。务必根据威胁模型、性能预期和观察到的数据特征验证生成的配置，并根据需要调整信标长度或分区数量。

### 关于信标长度的高级主题
<a name="w2aac15c25c29c19c11"></a>

 作为高级用户，在为解决方案选择合适的信标长度时，您可以更加灵活地选择合适的信标长度。您必须选择一个能够充分保护数据机密性的长度，同时最大限度地减少对查询性能的任何不必要影响。信标保留的安全程度取决于数据集的[分布](searchable-encryption.md#searchable-encryption-distribution)以及构造信标所依据的字段的[相关性](searchable-encryption.md#searchable-encryption-correlated-values)。
+  信标长度**过长**会导致产生的误报太少，并且可能会泄露有关数据集分布的区别信息。
+  信标长度**过短**会产生太多的误报，并且会增加查询的性能成本，因为它需要对数据库进行更广泛的扫描。

如果您的数据集分布大致均匀，则可以使用以下方程和过程来帮助估算适合您的实现的信标长度。这些方程提供了信标可能产生的平均误报数量的估计值，但它们并不能保证数据集中每个唯一值都有特定数量的误报。以下主题假设您的信标分布均匀，并且其中不包含相关数据。

1. **计算建议的预期碰撞次数范围**

   要确定给定字段的适当信标长度，您必须首先确定预期碰撞次数的适当范围。预期的碰撞次数表示映射到特定 HMAC 标签的唯一明文值的平均预期数量。一个唯一的明文值的预期误报数比预期的碰撞次数少一。

   建议预期的碰撞次数大于或等于二，且小于总量的平方根。只有当您的总量具有 16 个或更多唯一值时，以下方程才有效。

   ```
   2 ≤ number of collisions < √(Population)
   ```

   如果碰撞次数少于两次，则信标产生的误报数将会太少。建议将两个作为预期碰撞的最小数量，因为这意味着，平均来说，字段中的每个唯一值都会通过映射到另一个唯一值来产生至少一个误报。

1. **计算信标长度的建议范围**

   确定预期碰撞的最小和最大次数后，使用以下公式来确定适当信标长度的范围。

   ```
   number of collisions = Population * 2-(beacon length)
   ```

   首先，求解**信标长度**，其中预期碰撞次数等于二（建议的最小预期碰撞数）。

   ```
   2 = Population * 2-(beacon length)
   ```

   然后，求解**信标长度**，其中预期碰撞次数等于总量的平方根（建议的最小预期碰撞数）。

   ```
   √(Population) = Population * 2-(beacon length)
   ```

   建议将此方程产生的输出向下舍入到较短的信标长度。举例来说，如果方程产生的信标长度为 15.6，则建议将该值向下舍入到 15 位，而不是四舍五入到 16 位。

1. **选择信标长度**

   这些方程仅确定您的字段的建议信标长度范围。建议尽量使用较短的信标长度，以保护数据集的安全性。但是，您实际使用的信标长度却由您的威胁模型决定。在审查威胁模型以确定字段的最佳信标长度时，请考虑您的性能要求。

   使用较短的信标长度会降低查询性能，而使用较长的信标长度则会降低安全性。通常，如果您的数据集[分布](searchable-encryption.md#searchable-encryption-distribution)不均匀，或者您根据[相关](searchable-encryption.md#searchable-encryption-correlated-values)字段构造不同的信标，则需要使用较短的信标长度来最大限度地减少泄露的有关数据集分布的信息量。

   如果您查看威胁模型，并确定泄露的有关字段分布的任何区别信息不会对您的整体安全构成威胁，则可以选择使用比您计算的建议范围更长的信标长度。例如，如果将某个字段的建议信标长度范围计算为 9—16 位，则可以选择使用 24 位的信标长度来避免任何性能损失。

   请谨慎选择信标长度。使用信标写入新记录后，您将无法更新信标长度。

## 高级信标长度示例
<a name="beacon-length-example"></a>

假设一个在[加密操作](concepts.md#crypt-actions)中将 `unit` 字段标记为 `ENCRYPT_AND_SIGN` 的数据库。要为 `unit` 字段配置标准信标，我们需要确定 `unit` 字段的预期误报数量和信标长度。

1. 估算总量

   在审查了威胁模型和当前的数据库解决方案之后，预计 `unit` 字段最终将有 100000 个唯一值。

   这意味着**总量 = 100000**。

1. 计算预期碰撞次数的建议范围。

   在此示例中，预期的碰撞次数应当介于 2—316 之间。

   ```
   2 ≤ number of collisions < √(Population)
   ```

   1. 

      ```
      2 ≤ number of collisions < √({{100,000}})
      ```

   1. 

      ```
      2 ≤ number of collisions < {{316}}
      ```

1. 计算信标长度的建议范围。

   在本示例中，信标长度应当介于 9–16 位之间。

   ```
   number of collisions = Population * 2-(beacon length)
   ```

   1. 计算信标长度，其中预期的碰撞次数等于**步骤 2** 中确定的最小值。

      ```
      2 = 100,000 * 2-(beacon length)
      ```

      信标长度 = 15.6 或 15 位

   1. 计算信标长度，其中预期的碰撞次数等于**步骤 2** 中确定的最大值。

      ```
      316 = 100,000 * 2-(beacon length)
      ```

      信标长度 = 8.3 或 8 位

1. 确定适合您的安全和性能要求的信标长度。

   对于低于 15 的每一个位，性能成本和安全性会翻一番。
   + 16 位
     + 平均而言，每个唯一值将映射到 1.5 个其他单位。
     + 安全性：具有相同的截断 HMAC 标签的两条记录具有相同明文值的可能性为 66%。
     + 性能：查询将针对您实际请求的每 10 条记录检索 15 条记录。
   + 14 位
     + 平均而言，每个唯一值将映射到 6.1 个其他单位。
     + 安全性：具有相同的截断 HMAC 标签的两条记录具有相同明文值的可能性为 33%。
     + 性能：查询将针对您实际请求的每 10 条记录检索 30 条记录。