本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
適用於 Java 的 DynamoDB 加密用戶端的範例程式碼
注意
我們的用戶端加密程式庫已重新命名為 AWS 資料庫加密 SDK。下列主題提供有關適用於 Java 的 DynamoDB Encryption Client 版本 1.x —2.x 和適用於 Python 的 DynamoDB Encryption Client 版本 1.x —3.x 的資訊。如需詳細資訊,請參閱AWS 支援 SDK的 DynamoDB 資料庫加密版本。
下列範例示範如何使用 DynamoDB Encryption Client for Java 來保護應用程式中的 DynamoDB 資料表項目。您可以在 上aws-dynamodb-encryption-java
使用 DynamoDBEncryptor
此範例示範如何將較低層級 DynamoDBEncryptor
您可以搭配 使用任何相容的密碼編譯材料提供者 (CMP)DynamoDBEncryptor
,也可以搭配 DynamoDBMapper
和 使用 Direct KMS ProviderAttributeEncryptor。
請參閱完整的程式碼範例:AwsKmsEncryptedItem.java
- 步驟 1:建立直接KMS提供者
-
建立具有指定區域的 AWS KMS 用戶端執行個體。然後,使用用戶端執行個體,使用您偏好的 建立 Direct KMS Provider 執行個體 AWS KMS key。
此範例使用 Amazon Resource Name (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:建立項目
-
此範例定義代表範例資料表項目
record
HashMap 的 。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
-
DynamoDBEncryptor
使用 Direct KMS Provider 建立 的執行個體。final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);
- 步驟 4:建立 DynamoDB 加密內容
-
DynamoDB 加密內容包含資料表結構及其加密和簽署方式的相關資訊。如果您使用
DynamoDBMapper
,AttributeEncryptor
會為您建立加密細節。final String tableName = "testTable"; final EncryptionContext encryptionContext = new EncryptionContext.Builder() .withTableName(tableName) .withHashKeyName(partitionKeyName) .withRangeKeyName(sortKeyName) .build();
- 步驟 5:建立屬性動作物件
-
屬性動作決定項目的哪些屬性會加密並簽署,哪些屬性只會簽署,以及哪些屬性不會加密或簽署。
在 Java 中,若要指定屬性動作,您可以建立屬性名稱和
EncryptionFlags
值對 HashMap 的 。例如,下列 Java 程式碼會建立
actions
HashMap ,以加密和簽署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
下列範例示範如何將 DynamoDB 映射器協助程式類別與 Direct KMS Provider 搭配使用。Direct KMS Provider 會在您指定的 AWS KMS key AWS Key Management Service (AWS KMS) 中產生並保護其密碼編譯材料。
您可以搭配 使用任何相容的密碼編譯材料提供者 (CMP)DynamoDBMapper
,也可以搭配較低層級 使用 Direct KMS ProviderDynamoDBEncryptor
。
請參閱完整的程式碼範例:AwsKmsEncryptedObject.java
- 步驟 1:建立直接KMS提供者
-
建立具有指定區域的 AWS KMS 用戶端執行個體。然後,使用用戶端執行個體,使用您偏好的 建立 Direct KMS Provider 執行個體 AWS KMS key。
此範例使用 Amazon Resource Name (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 Encryptor,才能使用 DynamoDB Mapper。
接下來,建立 DynamoDB 資料庫的執行個體和映射器組態,並使用它們來建立 DynamoDB Mapper 的執行個體。
重要
使用
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 資料表
-
接下來,定義您的 DynamoDB 資料表。請使用註釋指定屬性動作。此範例會建立代表資料表項目的 DynamoDB 資料表
ExampleTable
、 和DataPoJo
類別。該範例資料表的主索引鍵屬性將經過簽署但未加密。這包括了標註
@DynamoDBHashKey
的partition_attribute
,以及標註@DynamoDBRangeKey
的sort_attribute
。凡是標註
@DynamoDBAttribute
的屬性 (例如some numbers
) 都將進行加密並簽署。例外是使用 DynamoDB Encryption Client 定義的@DoNotEncrypt
(僅簽署) 或@DoNotTouch
(不加密或簽署) 加密註釋的屬性。例如,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 Mapper 儲存該項目時,該項目會在新增至資料表之前自動加密和簽署。
本範例定義的資料表項目名為
record
。該項目儲存至資料表之前,其屬性將根據DataPoJo
類別中的註釋進行加密與簽署。就本例而言,所有屬性除了PartitionAttribute
、SortAttribute
和LeaveMe
以外都將加密並簽署。PartitionAttribute
和SortAttributes
只會進行簽署,而LeaveMe
屬性則完全未加密或簽署。若要加密並簽署
record
項目,然後將其加入至ExampleTable
,請呼叫DynamoDBMapper
類別的save
方法。由於您的 DynamoDB Mapper 已設定為使用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);