

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 可搜尋加密
<a name="searchable-encryption"></a>



|  | 
| --- |
| 我們的用戶端加密程式庫已重新命名為 AWS 資料庫加密 SDK。此開發人員指南仍提供有關 [DynamoDB 加密用戶端](legacy-dynamodb-encryption-client.md)的資訊。 | 

可搜尋加密可讓您在不解密整個資料庫的情況下搜尋加密的記錄。這是使用*信標來完成的*，該信標會在寫入欄位的純文字值與實際存放在資料庫中的加密值之間建立映射。 AWS 資料庫加密 SDK 會將信標存放在新增至記錄的新欄位中。根據您使用的信標類型，您可以對加密的資料執行完全相符的搜尋或更自訂的複雜查詢。

**注意**  
 AWS 資料庫加密 SDK 中的可搜尋加密與學術研究定義的可搜尋對稱加密不同，例如[可搜尋對稱加密](https://dl.acm.org/doi/10.1145/1180405.1180417)。



信標是截斷的雜湊型訊息驗證碼 (HMAC) 標籤，可將純文字欄位值映射至加密且可搜尋的識別符。當您將值寫入設定為可搜尋加密的加密欄位時， AWS 資料庫加密 SDK 會透過純文字值計算 HMAC。此 HMAC 輸出是該欄位純文字值的一對一 (1：1) 比對。軟體開發套件會刻意截斷 HMAC 輸出，讓多個不同的純文字值在相同的信標上碰撞。這些碰撞 （誤報） 會限制未經授權的使用者從頻率模式推斷敏感資訊的能力。當您查詢信標時， AWS 資料庫加密 SDK 會自動篩選掉這些誤報，並傳回查詢的純文字結果。為了進一步解決頻率洩漏的問題，會分割信標，允許相同的純文字值跨分割區產生不同的信標值。當資料表僅使用單一分割區時，此行為自然符合傳統、非分割區的信標。

每個信標的平均誤報數取決於截斷後的剩餘信標長度和分割區數。如需判斷適合您實作之信標長度的說明，請參閱[判斷信標長度](choosing-beacon-length.md)。

**注意**  
可搜尋加密旨在實作在新的未填入資料庫中。在現有資料庫中設定的任何信標只會映射上傳至資料庫的新記錄，信標無法映射現有資料。

**主題**
+ [信標是否適合我的資料集？](#are-beacons-right-for-me)
+ [可搜尋的加密案例](#beacon-overview-example)

## 信標是否適合我的資料集？
<a name="are-beacons-right-for-me"></a>

使用信標對加密的資料執行查詢，可降低與用戶端加密資料庫相關聯的效能成本。當您使用信標時，查詢的效率和有關資料分佈的公開資訊量之間存在固有權衡。信標不會變更 欄位的加密狀態。當您使用 AWS 資料庫加密 SDK 加密和簽署欄位時，該欄位的純文字值永遠不會公開給資料庫。資料庫會存放 欄位的隨機加密值。

信標會與其[計算來源的加密欄位](plan-searchable-encryption.md#plan-searchable-encryption.title)一起存放。這表示即使未經授權的使用者無法檢視加密欄位的純文字值，他們也可以對信標執行統計分析，以進一步了解資料集的分佈，並在極端情況下識別信標映射到的純文字值。適當的信標組態對於減輕這些風險至關重要。選取適當的信標長度和分割方案，透過限制任何單一信標中的值濃度，確保足夠的碰撞和緩解頻率型攻擊，以保持機密性。

**安全性與效能**
+ 信標長度越短，分割區計數越高，透過增加碰撞並減少頻率洩漏來提高安全性，
+ 較長的信標長度和較少的分割區可透過減少誤報和查詢廣發來改善效能。

在許多實際案例中，選擇良好的組態可以平衡這些競爭目標。不過，可搜尋加密可能無法為每個資料集提供所需的安全和效能層級。

在設定任何信標之前，請仔細檢閱您的威脅模型、安全需求和效能需求，並考慮資料集的唯一性特性，以判斷可搜尋加密是否為適當的選擇。

**分佈**  
信標的安全屬性取決於基礎資料的分佈以及信標的設定方式，包括使用的分割區數量。當您設定可搜尋加密的加密欄位時， AWS 資料庫加密 SDK 會在寫入該欄位的每個純文字值上計算 HMAC，並使用密碼編譯金鑰衍生信標。信標是在分割區的內容中計算，允許相同的純文字值跨分割區產生不同的信標值。當資料表僅使用單一分割區時，相同的純文字值一律會對應至相同的截斷 HMAC 標籤，這會保留原始資料集的頻率模式。  
具有高度偏斜分佈的欄位需要特別注意。例如，假設資料庫存放伊利諾州所有居民的居住城市。如果您從加密`City`欄位建構信標，則「芝加哥」值會比其他城市更頻繁發生。即使未經授權的使用者只能存取加密的項目和信標值，這種不平衡可能會允許他們透過觀察過度表示的信標來推斷哪些記錄對應到芝加哥居民。截斷信標可透過強制更多碰撞來減少此洩漏，但為了充分隱藏嚴重扭曲所需的信標長度，可能會因為誤報增加而產生顯著的效能額外負荷。  
若要安全地設定信標，您應該分析資料的頻率分佈，並了解截斷和分割如何互動。信標中保留的位元數目會決定公開多少統計資訊，而分割區數目則會限制任何單一信標值的集中程度。較短的信標長度和更多分割區可減少頻率洩漏，但會增加誤報和查詢廣發。較長的信標長度和較少的分割區可改善查詢效率，但會公開基礎分佈的詳細資訊。  
在某些情況下，當資料表僅使用單一分割區時，工作負載是不可行的。具有非常小人口或高度不平衡二進位結果的屬性，例如 NEGATIVE 值主導的醫療測試結果，無法單獨使用截斷進行保護。使用一個分割區時，信標短到足以隱藏分佈會將所有值摺疊為單一標籤，而較長的信標則讓罕見值易於識別。在這些情況下，需要分割的信標，才能進行可搜尋的加密。透過將過度表示的值分散到多個分割區，此方法可減少等效類別的大小，並以使用單一分割區時無法做到的方式限制頻率洩漏。

**關聯性**  
我們強烈建議您避免從具有相關值的欄位建構不同的信標。從相關欄位建構的信標需要較短的信標長度，才能充分將每個資料集分發給未經授權使用者的資訊量降至最低。您必須仔細分析資料集，包括其熵和相關值的關節分佈，以確定需要截斷多少信標。如果產生的信標長度不符合您的效能需求，則信標可能不適合您的資料集。  
例如，您不應該從 `City`和 `ZIPCode` 欄位建構兩個單獨的信標，因為郵遞區號可能只會與一個城市相關聯。一般而言，信標產生的誤報會限制未經授權的使用者識別資料集辨別資訊的能力。但是， `City`和 `ZIPCode` 欄位之間的相互關聯意味著未經授權的使用者可以輕鬆識別哪些結果是誤報，並區分不同的郵遞區號。  
您也應該避免從包含相同純文字值的欄位建構信標。例如，您不應該從 `mobilePhone`和 `preferredPhone` 欄位建構信標，因為它們可能具有相同的值。如果您從這兩個欄位建構不同的信標， AWS 資料庫加密 SDK 會在不同的金鑰下為每個欄位建立信標。這會為相同的純文字值產生兩個不同的 HMAC 標籤。這兩個不同的信標不太可能具有相同的誤報，未經授權的使用者可能可以區分不同的電話號碼。

即使您的資料集包含關聯欄位或分佈不均勻，您還是可以使用較短的信標長度來建構信標，以維護資料集的機密性。不過，信標長度不保證資料集中的每個唯一值都會產生許多誤報，有效將資料集的辨別資訊量降至最低。Beacon 長度只會預估產生的誤報平均數量。資料集的分佈越不平均，有效信標長度就越低，決定了產生的平均誤報次數。

仔細評估您選擇信標化的欄位分佈，並判斷需要多少截斷才能滿足您的安全需求。本章中的下列主題假設在每個分割區中，信標值是統一分佈的，並且基礎資料不會引入會削弱這些假設的相互關聯性。

## 可搜尋的加密案例
<a name="beacon-overview-example"></a>

下列範例示範可搜尋的加密解決方案，並說明本章討論的核心概念。在這種情況下，某些欄位值會非常頻繁地發生，如果使用單一分割區，這會導致大型等效類別和增加頻率洩漏。為了解決這個問題，組態使用多個分割區，以便更平均地分配高頻率的值，減少洩漏，同時保留執行有效等式搜尋的能力。

考慮名為 的資料庫`Employees`，以追蹤公司的員工資料。資料庫中的每個記錄都包含稱為 *EmployeeID*、*LastName*、*FirstName* 和 *Address* 的欄位。`Employees` 資料庫中的每個欄位都由主索引鍵 識別`EmployeeID`。

以下是資料庫中的純文字記錄範例。

```
{
    "EmployeeID": 101,
    "LastName": "Jones",
    "FirstName": "Mary",
    "Address": {
                "Street": "123 Main",
                "City": "Anytown",
                "State": "OH",
                "ZIPCode": 12345
    }
}
```

如果您在[密碼編譯動作](concepts.md#crypt-actions)`ENCRYPT_AND_SIGN`中將 `LastName`和 `FirstName` 欄位標記為 ，這些欄位中的值會在上傳至資料庫之前於本機加密。上傳的加密資料是完全隨機的，資料庫無法將此資料識別為受保護。它只會偵測典型的資料項目。這表示實際存放在資料庫中的記錄可能如下所示。

```
{
    "PersonID": 101,
    "LastName": "1d76e94a2063578637d51371b363c9682bad926cbd",
    "FirstName": "21d6d54b0aaabc411e9f9b34b6d53aa4ef3b0a35",
    "Address": {
                "Street": "123 Main",
                "City": "Anytown",
                "State": "OH",
                "ZIPCode": 12345
    }
}
```

如果您需要在 `LastName` 欄位中查詢資料庫的完全相符項目，[請設定名為 LastName 的標準信標](configure-beacons.md#config-standard-beacons)，將寫入`LastName`欄位的純文字值映射至存放在資料庫中的加密值。 *LastName* 

此信標會從 `LastName` 欄位中的純文字值計算 HMACs。每個 HMAC 輸出都會截斷，使其不再完全符合純文字值。例如， 的完整雜湊和截斷的雜湊`Jones`可能如下所示。

**完成雜湊**

`2aa4e9b404c68182562b6ec761fcca5306de527826a69468885e59dc36d0c3f824bdd44cab45526f70a2a18322000264f5451acf75f9f817e2b35099d408c833`

**截斷的雜湊**

`b35099d408c833`

在有許多員工的資料集中，例如 *Jones*、*Smith* 或 *Johnson* 等特定姓氏的發生頻率可能遠高於其他名稱。若要減少頻率洩漏並限制信標等效類別的大小，您應該將 **LastName** 信標設定為使用多個分割區。

啟用分割區時，每個項目都會在寫入時指派給分割區，而分割區編號會併入信標衍生。因此，具有相同姓氏的員工可能會映射到跨分割區的不同信標值。這會將高度頻繁的名稱分散到多個分割區，以減少任何單一信標值的過度表示。

設定標準信標之後，您可以在 `LastName` 欄位上執行等式搜尋。例如，如果您想要搜尋 `Jones`，請使用 *LastName* 信標來執行下列查詢。

```
LastName = Jones
```

查詢特定高頻率姓氏時，例如 **Jones**，應用程式應該使用 **LastName** 信標為每個分割區發出一個查詢。 AWS 資料庫加密 SDK 接著會解密結果，並自動篩選掉任何誤報，傳回正確的純文字記錄。