Java 加密用戶端的範例程式碼 - AWS 資料庫加密 SDK

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

Java 加密用戶端的範例程式碼

注意

我們的客戶端加密庫被重命名為AWS數據庫加密 SDK。下列主題提供有關版本 1 的資訊。 X-2. Java 和版本 1 的動態驗證加密客戶端的 xX — 3. 適用於 Python 的 x 個加密用戶端。如需詳細資訊,請參閱適用於 DynamoDB 版本支援的資AWS料庫加密 SDK

下列範例說明如何使用適用於 Java 的 DynamoDB 加密用戶端來保護應用程式中的 DynamoDB 表格項目。您可以在aws-dynamodb-encryption-java存儲庫的示例目錄中找到更多示例(並提供您自己的示例)GitHub。

使用 DynamoDBEncryptor

這個範例說明如何使用較低層級的 DynamoDBEncryptor 搭配直接 KMS 提供者。直接 KMS 提供者會根據您指定的 AWS KMS keyin AWS Key Management Service (AWS KMS) 產生並保護其加密資料。

您可以搭配使用任何相容的加密資料提供者 (CMP)DynamoDBEncryptor,也可以使用直接 KMS 提供者和. DynamoDBMapper AttributeEncryptor

請參閱完整的代碼示例AwsKmsEncryptedItem.java

步驟 1:建立直接 KMS 提供者

使用指定區域建立 AWS KMS 用戶端執行個體。然後,使用用戶端執行個體建立具有您偏好的 Direct KMS 提供者執行個體AWS KMS key。

此範例使用 Amazon 資源名稱 (ARN) 來識別AWS KMS key,但您可以使用任何有效的金鑰識別碼。

final String keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' final String region = 'us-west-2' final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build(); final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, keyArn);
步驟 2:建立項目

這個範例recordHashMap會定義代表範例資料表項目的一個。

final String partitionKeyName = "partition_attribute"; final String sortKeyName = "sort_attribute"; final Map<String, AttributeValue> record = new HashMap<>(); record.put(partitionKeyName, new AttributeValue().withS("value1")); record.put(sortKeyName, new AttributeValue().withN("55")); record.put("example", new AttributeValue().withS("data")); record.put("numbers", new AttributeValue().withN("99")); record.put("binary", new AttributeValue().withB(ByteBuffer.wrap(new byte[]{0x00, 0x01, 0x02}))); record.put("test", new AttributeValue().withS("test-value"));
步驟 3:建立 DynamoDBEncryptor

使用直接 KMS 提供者建立 DynamoDBEncryptor 的執行個體。

final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);
步驟 4:建立 DynamoDB 加密內容

DynamoDB 加密內容包含資料表結構及其加密和簽署方式的相關資訊。如果您使用 DynamoDBMapperAttributeEncryptor 會為您建立加密細節。

final String tableName = "testTable"; final EncryptionContext encryptionContext = new EncryptionContext.Builder() .withTableName(tableName) .withHashKeyName(partitionKeyName) .withRangeKeyName(sortKeyName) .build();
步驟 5:建立屬性動作物件

屬性動作決定項目的哪些屬性會加密並簽署,哪些屬性只會簽署,以及哪些屬性不會加密或簽署。

在 Java 中,若要指定屬性動作,您可以建立屬性HashMap名稱和EncryptionFlags值配對的屬性。

例如,下列 Java 程式碼會建立一actionsHashMap個加密並簽署record項目中的所有屬性,但分割索引鍵和排序索引鍵屬性除外 (已簽署但未加密),以及未簽署或加密的test屬性。

final EnumSet<EncryptionFlags> signOnly = EnumSet.of(EncryptionFlags.SIGN); final EnumSet<EncryptionFlags> encryptAndSign = EnumSet.of(EncryptionFlags.ENCRYPT, EncryptionFlags.SIGN); final Map<String, Set<EncryptionFlags>> actions = new HashMap<>(); for (final String attributeName : record.keySet()) { switch (attributeName) { case partitionKeyName: // fall through to the next case case sortKeyName: // Partition and sort keys must not be encrypted, but should be signed actions.put(attributeName, signOnly); break; case "test": // Neither encrypted nor signed break; default: // Encrypt and sign all other attributes actions.put(attributeName, encryptAndSign); break; } }
步驟 6:將項目加密並簽署

若要加密並簽署資料表項目,請在 encryptRecord 的執行個體上呼叫 DynamoDBEncryptor 方法。指定資料表項目 (record)、屬性動作 (actions) 及加密細節 (encryptionContext)。

final Map<String, AttributeValue> encrypted_record = encryptor.encryptRecord(record, actions, encryptionContext);
步驟 7:將項目放入 DynamoDB 表格中

最後,將加密和已簽署的項目放入 DynamoDB 表格中。

final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient(); ddb.putItem(tableName, encrypted_record);

使用 DynamoDBMapper

下列範例顯示如何搭配直接 KMS 提供者使用 DynamoDB 對應程式協助程式類別。直接 KMS 提供者會根據您指定的 AWS KMS keyin AWS Key Management Service (AWS KMS) 產生並保護其加密資料。

您可以使用任何相容的密碼編譯資料提供者 (CMP) 搭配 DynamoDBMapper,而且可以使用直接 KMS 提供者搭配較低層級的 DynamoDBEncryptor

請參閱完整的代碼示例AwsKmsEncryptedObject.java

步驟 1:建立直接 KMS 提供者

使用指定區域建立 AWS KMS 用戶端執行個體。然後,使用用戶端執行個體建立具有您偏好的 Direct KMS 提供者執行個體AWS KMS key。

此範例使用 Amazon 資源名稱 (ARN) 來識別AWS KMS key,但您可以使用任何有效的金鑰識別碼。

final String keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' final String region = 'us-west-2' final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build(); final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, keyArn);
步驟 2:建立 DynamoDB 加密程式和 DynamoDBMapper

使用您在上一個步驟中建立的直接 KMS 提供者建立 DynamoDB 加密器的執行個體。您必須具現化較低層級的 DynamoDB 加密程式,才能使用 DynamoDB 對應程式。

接下來,建立 DynamoDB 資料庫的執行個體和對應程式組態,並使用它們建立 DynamoDB 對應器的執行個體。

重要

使用 DynamoDBMapper 加入或編輯已簽署 (或已加密並簽署) 的項目時,請將其設定成使用儲存行為 (例如 PUT) 納入所有屬性,如以下範例所示。否則,您將可能無法解密資料。

final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp) final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.standard().withRegion(region).build(); DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder().withSaveBehavior(SaveBehavior.PUT).build(); DynamoDBMapper mapper = new DynamoDBMapper(ddb, mapperConfig, new AttributeEncryptor(encryptor));
步驟 3:定義您的動態資料表

接下來,定義您的動態資料表。請使用註釋指定屬性動作。此範例會建立 DynamoDB 資料表ExampleTable,以及代表資料表項目的DataPoJo類別。

該範例資料表的主索引鍵屬性將經過簽署但未加密。這包括了標註 @DynamoDBHashKeypartition_attribute,以及標註 @DynamoDBRangeKeysort_attribute

凡是標註 @DynamoDBAttribute 的屬性 (例如 some numbers) 都將進行加密並簽署。例外情況是使用 DynamoDB 加密用戶端定義的 @DoNotTouch (僅簽署) 或 (不加密或簽署) 加密註釋的屬性。@DoNotEncrypt例如,leave me 屬性由於設有 @DoNotTouch 註釋,其將不會進行加密或簽署。

@DynamoDBTable(tableName = "ExampleTable") public static final class DataPoJo { private String partitionAttribute; private int sortAttribute; private String example; private long someNumbers; private byte[] someBinary; private String leaveMe; @DynamoDBHashKey(attributeName = "partition_attribute") public String getPartitionAttribute() { return partitionAttribute; } public void setPartitionAttribute(String partitionAttribute) { this.partitionAttribute = partitionAttribute; } @DynamoDBRangeKey(attributeName = "sort_attribute") public int getSortAttribute() { return sortAttribute; } public void setSortAttribute(int sortAttribute) { this.sortAttribute = sortAttribute; } @DynamoDBAttribute(attributeName = "example") public String getExample() { return example; } public void setExample(String example) { this.example = example; } @DynamoDBAttribute(attributeName = "some numbers") public long getSomeNumbers() { return someNumbers; } public void setSomeNumbers(long someNumbers) { this.someNumbers = someNumbers; } @DynamoDBAttribute(attributeName = "and some binary") public byte[] getSomeBinary() { return someBinary; } public void setSomeBinary(byte[] someBinary) { this.someBinary = someBinary; } @DynamoDBAttribute(attributeName = "leave me") @DoNotTouch public String getLeaveMe() { return leaveMe; } public void setLeaveMe(String leaveMe) { this.leaveMe = leaveMe; } @Override public String toString() { return "DataPoJo [partitionAttribute=" + partitionAttribute + ", sortAttribute=" + sortAttribute + ", example=" + example + ", someNumbers=" + someNumbers + ", someBinary=" + Arrays.toString(someBinary) + ", leaveMe=" + leaveMe + "]"; } }
步驟 4:加密並儲存資料表項目

現在,當您建立資料表項目並使用 DynamoDB 對應器儲存該項目時,項目會在新增至表格之前自動加密並簽署。

本範例定義的資料表項目名為 record。該項目儲存至資料表之前,其屬性將根據 DataPoJo 類別中的註釋進行加密與簽署。就本例而言,所有屬性除了 PartitionAttributeSortAttributeLeaveMe 以外都將加密並簽署。PartitionAttributeSortAttributes 只會進行簽署,而 LeaveMe 屬性則完全未加密或簽署。

若要加密並簽署 record 項目,然後將其加入至 ExampleTable,請呼叫 DynamoDBMapper 類別的 save 方法。由於 DynamoDB 對應器已設定為使用PUT儲存行為,因此該項目會以相同的主索引鍵取代任何項目,而不是更新它。這可確保簽章相符,而且您從資料表取得該項目後便能將其解密。

DataPoJo record = new DataPoJo(); record.setPartitionAttribute("is this"); record.setSortAttribute(55); record.setExample("data"); record.setSomeNumbers(99); record.setSomeBinary(new byte[]{0x00, 0x01, 0x02}); record.setLeaveMe("alone"); mapper.save(record);