使用 Java 用戶端加密 DynamoDB 式庫 - AWS 資料庫加密 SDK

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

使用 Java 用戶端加密 DynamoDB 式庫

我們的用戶端加密程式庫已重新命名為 AWS 資料庫加密 SDK。本開發人員指南仍提供 DynamoDB 加密用戶端的相關資訊。

本主題說明第 3 版中的一些函數和輔助類別。 適用於 Java 用戶端加密程式 DynamoDB x 個。

如需有關使用適用於 DynamoDB 之 Java 用戶端加密程式庫進行程式設計的詳細資訊,請參閱 Java 範例 (位於上的 aws-database-encryption-sdk-dynamodb 儲存庫中的 Java 範例)。 GitHub

項目加密程式

DynamoDB 的 AWS 資料庫加密開發套件在其核心是項目加密程式。您可以使用版本 3。 DynamoDB 的 Java 用戶端加密程式庫的 x 個,可透過下列方式加密、簽署、驗證和解密 DynamoDB 表格項目。

增強型用戶端

您可以將 DynamoDB 增強型用戶端設定為使用 Dynam PutItem oDB DynamoDbEncryptionInterceptor 請求自動加密和簽署用戶端項目。使用 DynamoDB 增強型用戶端,您可以使用帶註解的資料類別定義屬性動作。我們建議盡可能使用 DynamoDB 增強型用戶端。

DynamoDB 增強型用戶端不支援可搜尋的加密。

注意

資 AWS 料庫加密 SDK 不支援巢狀屬性的註解。

低階 DynamoDB API

您可以使用設定低階 DynamoDB API,以使用 Dynam oDB DynamoDbEncryptionInterceptor 請求在用戶端自動加密和簽署項目。PutItem

您必須使用低階 DynamoDB API 才能使用可搜尋的加密。

較低級別 DynamoDbItemEncryptor

較低層級會DynamoDbItemEncryptor直接加密、簽署或解密並驗證您的資料表項目,而無需呼叫 DynamoDB。它不會發出 DynamoDB PutItemGetItem請求。例如,您可以使用較低層級直DynamoDbItemEncryptor接解密和驗證已擷取的 DynamoDB 項目。

較低級別DynamoDbItemEncryptor不支持可搜索的加密

適用於 DynamoDB 的 AWS 資料庫加密開發套件中的屬性動作

屬性動作決定哪些屬性值已加密和簽署、哪些屬性值僅經過簽署、已簽署並包含在加密前後關聯中,以及忽略哪些值。

注意

若要使用加SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT密動作,您必須使用 3.3 版或更新版本的 AWS 資料庫加密 SDK。在更新要包含的資料模型之前,請先將新版本部署至所有讀取器SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT

如果您使用低階 DynamoDB API 或較低層級DynamoDbItemEncryptor,則必須手動定義屬性動作。如果您使用 DynamoDB 增強型用戶端,則可以手動定義屬性動作,也可以使用帶註解的資料類別來產生. TableSchema 為了簡化配置過程,我們建議使用帶註釋的數據類。當您使用已註解的資料類別時,您只需要對物件建模一次。

注意

定義屬性動作之後,您必須定義哪些屬性要從簽章中排除。為了方便日後新增 future 簽署的屬性,我們建議您選擇不同的前置詞 (例如 ":「) 來識別未簽署的屬性。在定義 DynamoDB 結構描述和屬性動DO_NOTHING作時標記的所有屬性的屬性名稱中包含此前置詞。

使用帶註解的資料類別,透過 DynamoDB 增強型用戶端和指定您的屬性動作。DynamoDbEncryptionInterceptor適用於 DynamoDB 的 AWS 資料庫加密開發套件使用標準 DynamoDB 屬性註釋來定義屬性類型,以決定如何保護屬性。除了主要索引鍵 (簽署但不加密) 以外,所有屬性都預設會進行加密和簽署。

注意

若要使用加SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT密動作,您必須使用 3.3 版或更新版本的 AWS 資料庫加密 SDK。在更新要包含的資料模型之前,請先將新版本部署至所有讀取器SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT

如需有關 DynamoDB 增強型用戶端註釋的詳細指引,請參閱上 GitHub 的 aws-database-encryption-sdk-dynamodb 儲存庫中的 SimpleClass.java。

根據預設,主索引鍵屬性會經過簽署但未加密 (SIGN_ONLY),而且所有其他屬性都會加密並簽署 (ENCRYPT_AND_SIGN)。如果您將任何屬性定義為SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,則分割區和排序屬性也必須是SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT。若要指定例外狀況,請使用 DynamoDB 的 Java 用戶端加密程式庫中定義的加密註解。例如,如果您只想簽署特定屬性,請使用@DynamoDbEncryptionSignOnly註釋。如果您想要將特定屬性簽署並包含在加密內容中,請使用@DynamoDbEncryptionSignAndIncludeInEncryptionContext. 如果您希望特定屬性既不簽名也不加密(DO_NOTHING),請使用@DynamoDbEncryptionDoNothing註釋。

注意

資 AWS 料庫加密 SDK 不支援巢狀屬性的註解。

下列範例顯示用來定義ENCRYPT_AND_SIGNSIGN_ONLY、和DO_NOTHING屬性動作的註釋。如需顯示用於定義之註釋的範例SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,請參閱 SimpleClass4.java

@DynamoDbBean public class SimpleClass { private String partitionKey; private int sortKey; private String attribute1; private String attribute2; private String attribute3; @DynamoDbPartitionKey @DynamoDbAttribute(value = "partition_key") public String getPartitionKey() { return this.partitionKey; } public void setPartitionKey(String partitionKey) { this.partitionKey = partitionKey; } @DynamoDbSortKey @DynamoDbAttribute(value = "sort_key") public int getSortKey() { return this.sortKey; } public void setSortKey(int sortKey) { this.sortKey = sortKey; } public String getAttribute1() { return this.attribute1; } public void setAttribute1(String attribute1) { this.attribute1 = attribute1; } @DynamoDbEncryptionSignOnly public String getAttribute2() { return this.attribute2; } public void setAttribute2(String attribute2) { this.attribute2 = attribute2; } @DynamoDbEncryptionDoNothing public String getAttribute3() { return this.attribute3; } @DynamoDbAttribute(value = ":attribute3") public void setAttribute3(String attribute3) { this.attribute3 = attribute3; } }

使用註釋的數據類來創建顯示在下面的代碼片段。TableSchema

final TableSchema<SimpleClass> tableSchema = TableSchema.fromBean(SimpleClass.class);

若要手動指定屬性動作,請建立一個Map物件,其中的名稱-值配對代表屬性名稱和指定動作。

指定ENCRYPT_AND_SIGN要加密和簽署屬性。指定SIGN_ONLY要簽署屬性,但不加密。指SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT定簽署屬性並將其包含在加密內容中。您無法在未簽署屬性的情況下加密屬性。指DO_NOTHING定忽略屬性。

分割區和排序屬性必須是SIGN_ONLYSIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT。如果您將任何屬性定義為SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,則分割區和排序屬性也必須是SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT

注意

若要使用加SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT密動作,您必須使用 3.3 版或更新版本的 AWS 資料庫加密 SDK。在更新要包含的資料模型之前,請先將新版本部署至所有讀取器SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT

final Map<String, CryptoAction> attributeActionsOnEncrypt = new HashMap<>(); // The partition attribute must be signed attributeActionsOnEncrypt.put("partition_key", CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT); // The sort attribute must be signed attributeActionsOnEncrypt.put("sort_key", CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT); attributeActionsOnEncrypt.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN); attributeActionsOnEncrypt.put("attribute2", CryptoAction.SIGN_ONLY); attributeActionsOnEncrypt.put("attribute3", CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT); attributeActionsOnEncrypt.put(":attribute4", CryptoAction.DO_NOTHING);

適用於 DynamoDB 的 AWS 資料庫加密開發套件中的加密組態

使用 AWS 資料庫加密 SDK 時,您必須為 DynamoDB 表格明確定義加密組態。加密配置中所需的值取決於您是手動定義屬性動作還是使用帶註釋的資料類別定義。

下列程式碼片段使用 DynamoDB 增強型用戶端定義 DynamoDB 表格加密組態 TableSchema,以及允許透過不同前置詞定義的未簽署屬性。

final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>(); tableConfigs.put(ddbTableName, DynamoDbEnhancedTableEncryptionConfig.builder() .logicalTableName(ddbTableName) .keyring(kmsKeyring) .allowedUnsignedAttributePrefix(unsignedAttrPrefix) .schemaOnEncrypt(tableSchema) // Optional: only required if you use beacons .search(SearchConfig.builder() .writeVersion(1) // MUST be 1 .versions(beaconVersions) .build()) .build());
邏輯資料表名稱

您的 DynamoDB 資料表的邏輯資料表名稱。

邏輯資料表名稱會以密碼編譯方式繫結至儲存在資料表中的所有資料,以簡化 DynamoDB 還原作業。強烈建議您在第一次定義加密組態時,將 DynamoDB 表名稱指定為邏輯資料表名稱。您必須永遠指定相同的邏輯資料表名稱。若要成功解密,邏輯資料表名稱必須與加密時指定的名稱相符。如果您的 DynamoDB 表名稱在從備份還原 DynamoDB 資料表後發生變更,邏輯資料表名稱可確保解密作業仍可辨識該資料表。

允許不帶正負號

屬性動作DO_NOTHING中標記的屬性。

允許的未簽名屬性會告訴用戶端哪些屬性會從簽章中排除。用戶端假設所有其他屬性都包含在簽章中。然後,在解密記錄時,用戶端會決定需要驗證哪些屬性,以及從您指定的允許未簽署屬性中忽略哪些屬性。您無法從允許的未簽署屬性中移除屬性。

您可以建立列出所有屬性的陣列,明確定義允許的無正負號DO_NOTHING屬性。您還可以在命名DO_NOTHING屬性時指定不同的前綴,並使用前綴告訴客戶端哪些屬性未簽名。我們強烈建議您指定不同的前置詞,因為這樣可以簡化 future 新增DO_NOTHING屬性的程序。如需詳細資訊,請參閱 更新您的資料模型

如果您未指定所有DO_NOTHING屬性的前置詞,您可以設定allowedUnsignedAttributes陣列,明確列出用戶端在解密時遇到這些屬性時應該未簽署的所有屬性。您應該只在絕對必要時明確定義允許的未簽名屬性。

搜尋組態 (選擇性)

SearchConfig信標版本

SearchConfig必須指定為使用可搜尋的加密已簽署的信標

演算法套件 (選擇性)

algorithmSuiteId義了 AWS 資料庫加密 SDK 使用的演算法套件。

除非您明確指定替代演算法套件,否則資 AWS 料庫加密 SDK 會使用預設演算法套件。預設演算法套件使用 AES-GCM 演算法搭配金鑰衍生、數位簽章和金鑰承諾。雖然預設演算法套件可能適用於大多數應用程式,但您可以選擇替代演算法套件。例如,某些信任模型會由沒有數位簽章的演算法套件來滿足。如需有關「資 AWS 料庫加密 SDK」支援的演算法套件的資訊,請參閱AWS 資料庫加密 SDK 中支援的演算法套件

若要選取不含 ECDSA 數位簽章的 AES-GCM 演算法套件,請在資料表加密組態中包含下列程式碼片段。

.algorithmSuiteId( DBEAlgorithmSuiteId.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_SYMSIG_HMAC_SHA384)

使用 AWS 資料庫加密 SDK 更新項目

UpdateItem對於已加密或簽署的項目, AWS 資料庫加密 SDK 不支援 ddb:。若要更新加密或簽署的項目,您必須使用 ddb: PutItem。當您在請求中指定與現有項目相同的主PutItem索引鍵時,新項目會完全取代現有項目。更新項目後,您還可以使用 CLOBBER 清除和替換保存時的所有屬性。

解密簽署的集

在 AWS 資料庫加密 SDK 版本 3.0.0 和 3.1.0 版中,如果您將設定類型屬性定義為SIGN_ONLY,則會依照提供的順序規範化集合的值。DynamoDB 不會保留集合的順序。因此,包含該集合的項目的簽名驗證可能會失敗。當集合的值以與提供給 AWS 資料庫加密 SDK 不同的順序傳回時,簽章驗證會失敗,即使集合屬性包含相同的值也一樣。

注意

版本 3.1.1 及更新版本的 AWS 資料庫加密 SDK 會規範化所有設定類型屬性的值,以便讀取值的順序與寫入 DynamoDB 的順序相同。

如果簽章驗證失敗,解密作業就會失敗,並傳回下列錯誤訊息。

加密軟件 .dbencryptionsdk 結構加密. StructuredEncryptionException:沒有符合的收件者標籤。

如果您收到上述錯誤訊息,並認為您嘗試解密的項目包含使用 3.0.0 或 3.1.0 版簽署的集合,請參閱上的 aws-database-encryption-sdk-dynamodb-java 存放庫DecryptWithPermute目錄,以取得有關如何成功驗證集的 GitHub 詳細資訊。