

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# AWS DynamoDB용 Database Encryption SDK
<a name="dynamodb-encryption-client"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

 AWS Database Encryption SDK for DynamoDB는 [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/) 설계에 클라이언트 측 암호화를 포함할 수 있는 소프트웨어 라이브러리입니다. AWS Database Encryption SDK for DynamoDB는 속성 수준 암호화를 제공하며 암호화할 항목과 데이터의 신뢰성을 보장하는 서명에 포함할 항목을 지정할 수 있습니다. 전송 중 및 유휴 상태의 중요 데이터를 암호화하면 일반 텍스트 데이터를 AWS을 포함한 제3자가 사용할 수 없게 하는 데 도움이 됩니다.

**참고**  
 AWS Database Encryption SDK는 PartiQL을 지원하지 않습니다.

DynamoDB에서 [테이블](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.TablesItemsAttributes)은 항목 모음입니다. 각 *항목*은 *속성* 모음입니다. 각 속성마다 이름과 값이 있습니다. AWS Database Encryption SDK for DynamoDB는 속성 값을 암호화합니다. 그런 다음 속성에 대한 서명을 계산합니다. 암호화할 속성 값과 [암호화 작업](concepts.md#crypt-actions)의 서명에 포함할 속성 값을 지정합니다.

이 장의 주제에서는 암호화된 필드, 클라이언트 설치 및 구성에 대한 지침, 시작하는 데 도움이 되는 Java 예제를 포함하여 DynamoDB용 AWS Database Encryption SDK에 대한 개요를 제공합니다.

**Topics**
+ [클라이언트측 및 서버 측 암호화](client-server-side.md)
+ [암호화 및 서명되는 필드](DDB-encrypted-and-signed.md)
+ [DynamoDB의 검색 가능한 암호화](ddb-searchable-encryption.md)
+ [데이터 모델 업데이트](ddb-update-data-model.md)
+ [AWS Database Encryption SDK for DynamoDB 사용 가능한 프로그래밍 언어](ddb-programming-languages.md)
+ [레거시 DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)

# 클라이언트측 및 서버 측 암호화
<a name="client-server-side"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

 AWS Database Encryption SDK for DynamoDB는 데이터베이스로 전송하기 전에 테이블 데이터를 암호화하는 *클라이언트 측 암호화*를 지원합니다. 하지만 DynamoDB는 테이블을 디스크에 보관할 때 테이블을 사용자 모르게 암호화하고 사용자가 테이블에 액세스할 때 복호화하는 서버 측 *저장 데이터 암호화* 기능을 제공합니다.

선택하는 도구는 데이터의 민감도와 애플리케이션의 보안 요구 사항에 따라 달라집니다. DynamoDB용 AWS Database Encryption SDK와 저장 데이터 암호화를 모두 사용할 수 있습니다. 암호화 및 서명된 항목을 DynamoDB로 전송하는 경우 DynamoDB는 항목을 보호 중인 상태로 인식하지 못하며, 이진 속성 값을 가진 일반적인 테이블 항목만 탐지합니다.

**서버 측 저장 데이터 암호화**

DynamoDB는 테이블을 디스크에 보관할 때 DynamoDB에서 테이블을 사용자 모르게 암호화하고 사용자가 테이블 데이터에 액세스할 때 복호화하는 [저장 중 암호화](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/EncryptionAtRest.html), *서버 측 암호화* 기능을 지원합니다.

 AWS SDK를 사용하여 DynamoDB와 상호 작용하는 경우 기본적으로 데이터는 HTTPS 연결을 통해 전송 중에 암호화되고 DynamoDB 엔드포인트에서 해독된 다음 DynamoDB에 저장되기 전에 다시 암호화됩니다.
+ **암호화 기본 제공.** DynamoDB는 모든 테이블을 작성할 때 투명하게 암호화하고 복호화합니다. 저장 데이터 암호화를 활성화하거나 비활성화할 수 없습니다.
+ **DynamoDB는 암호화 키를 만들고 관리합니다.** 각 테이블의 고유 키는 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS)을 암호화되지 않은 상태로 남기지 않는 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)로 보호됩니다. 기본적으로 DynamoDB는 DynamoDB 서비스 계정의 [AWS 소유 키](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-owned-cmk)를 사용하지만, 계정에서 [AWS 관리형 키](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-managed-cmk) 또는 [고객 관리 키](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk)를 선택하여 일부 또는 모든 테이블을 보호할 수 있습니다.
+ **디스크에 대한 모든 테이블 데이터는 암호화됩니다.** 암호화된 테이블이 디스크에 저장될 때 는 [프라이머리 키](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)와 로컬 및 글로벌[ 보조 인덱스](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.SecondaryIndexes)를 포함하여 모든 테이블 데이터를 암호화합니다. 테이블에 정렬 키가 있는 경우 범위 경계를 표시하는 정렬 키 중 일부가 테이블 메타데이터에 일반 텍스트 형태로 저장됩니다.
+ **테이블과 관련된 객체도 암호화됩니다.** 저장 데이터 암호화는 [DynamoDB 스트림](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html), [전역 테이블](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html), [백업](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/BackupRestore.html)이 내구성 있는 미디어에 기록될 때마다 보호합니다.
+ **항목에 액세스하면 해당 항목의 암호가 복호화됩니다.** 테이블에 액세스할 때 DynamoDB는 대상 항목을 포함하는 테이블의 부분을 복호화하고 일반 텍스트 항목을 사용자에게 반환합니다.

**AWS DynamoDB용 Database Encryption SDK**

클라이언트측 암호화는 소스에서 DynamoDB의 스토리지에 이르기까지 전송 중 및 저장 중인 데이터에 대한 엔드투엔드 보호를 제공합니다. 일반 텍스트 데이터는를 포함한 제3자에게 절대 노출되지 않습니다 AWS. 새 DynamoDB 테이블과 함께 AWS Database Encryption SDK for DynamoDB를 사용하거나 기존 Amazon DynamoDB 테이블을 최신 버전의 AWS Database Encryption SDK for DynamoDB로 마이그레이션할 수 있습니다.
+ **데이터가 전송 및 저장 시 보호되며,** 를 포함한 제3자에게 절대 노출되지 않습니다 AWS.
+ **테이블 항목에 서명할 수 있습니다.** AWS Database Encryption SDK for DynamoDB에 프라이머리 키 속성을 포함하여 테이블 항목 전체 또는 일부에 대한 서명을 계산하도록 지시할 수 있습니다. 이 서명을 사용하면 속성 추가 또는 삭제, 속성 값 바꾸기 등 항목에 대한 무단 변경 내용을 전체적으로 감지할 수 있습니다.
+ [키링을 선택](keyrings.md)하여** 데이터 보호 방법을 결정합니다**. 키링에 따라 데이터 키, 궁극적으로 데이터를 보호하는 래핑 키가 결정됩니다. 작업에 가장 적합한 가장 안전한 래핑 키를 사용하세요.
+ ** AWS Database Encryption SDK for DynamoDB는 전체 테이블을 암호화하지 않습니다.** 항목에서 암호화할 속성을 선택할 수 있습니다. AWS Database Encryption SDK for DynamoDB는 전체 항목을 암호화하지 않습니다. 속성 이름 또는 프라이머리 키(파티션 키 및 정렬 키) 속성의 이름 또는 값은 암호화하지 않습니다.

**AWS Encryption SDK**

DynamoDB에 저장하는 데이터를 암호화하는 경우 AWS Database Encryption SDK for DynamoDB를 사용하는 것이 좋습니다.

[AWS Encryption SDK](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/)는 일반 데이터를 암호화 및 복호화할 수 있도록 도와주는 클라이언트측 암호화 라이브러리입니다. 모든 유형의 데이터를 보호할 수 있지만 데이터베이스 레코드와 같은 정형 데이터에는 사용할 수 있도록 설계되지 않았습니다. DynamoDB용 AWS Database Encryption SDK와 달리는 항목 수준 무결성 검사를 제공할 AWS Encryption SDK 수 없으며 속성을 인식하거나 기본 키의 암호화를 방지하는 로직이 없습니다.

 AWS Encryption SDK 를 사용하여 테이블의 요소를 암호화하는 경우 DynamoDB용 AWS Database Encryption SDK와 호환되지 않습니다. 한 라이브러리로는 암호화하고 다른 라이브러리로는 복호화할 수 없습니다.

# 암호화 및 서명되는 필드
<a name="DDB-encrypted-and-signed"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

 AWS Database Encryption SDK for DynamoDB는 Amazon DynamoDB 애플리케이션용으로 특별히 설계된 클라이언트 측 암호화 라이브러리입니다. Amazon DynamoDB는 항목 모음인 [테이블](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.TablesItemsAttributes)에 데이터를 저장합니다. 각 *항목*은 *속성* 모음입니다. 각 속성마다 이름과 값이 있습니다. AWS Database Encryption SDK for DynamoDB는 속성 값을 암호화합니다. 그런 다음 속성에 대한 서명을 계산합니다. 암호화할 속성 값과 서명에 포함할 속성 값을 지정할 수 있습니다.

암호화는 속성 값의 기밀성을 보호합니다. 서명은 서명된 모든 속성과 속성 간 관계의 무결성을 제공하고 인증을 제공합니다. 속성을 추가 또는 삭제하거나 암호화된 값을 다른 값으로 대체하는 등 항목 전체에 대한 무단 변경을 탐지할 수 있습니다.

암호화된 항목에서 테이블 이름, 모든 속성 이름, 암호화하지 않은 속성 값, 프라이머리 키(파티션 키 및 정렬 키) 속성의 이름과 값, 속성 유형을 포함한 일부 데이터는 일반 텍스트로 유지됩니다. 이 필드에는 민감한 데이터를 저장하지 마세요.

 AWS Database Encryption SDK for DynamoDB의 작동 방식에 대한 자세한 내용은 섹션을 참조하세요[AWS Database Encryption SDK 작동 방식](how-it-works.md).

**참고**  
 AWS Database Encryption SDK for DynamoDB 주제의 *속성 작업에* 대한 모든 언급은 [암호화 작업을](concepts.md#crypt-actions) 참조합니다.

**Topics**
+ [속성 값 암호화](#encrypt-attribute-values)
+ [항목에 서명](#sign-the-item)

## 속성 값 암호화
<a name="encrypt-attribute-values"></a>

 AWS Database Encryption SDK for DynamoDB는 지정한 속성의 값(속성 이름 또는 유형은 아님)을 암호화합니다. 암호화된 속성 값을 확인하려면 [속성 작업](concepts.md#crypt-actions)을 사용합니다.

예를 들어 이 항목에는 `example` 및 `test` 속성이 포함됩니다.

```
'example': 'data',
'test': 'test-value',
...
```

`example` 속성을 암호화하지만 `test` 속성을 암호화하지 않으면 결과는 다음과 같습니다. 암호화된 `example` 속성 값은 문자열이 아닌 이진 데이터입니다.

```
'example': Binary(b"'b\x933\x9a+s\xf1\xd6a\xc5\xd5\x1aZ\xed\xd6\xce\xe9X\xf0T\xcb\x9fY\x9f\xf3\xc9C\x83\r\xbb\\"),
'test': 'test-value'
...
```

각 항목의 프라이머리 키 속성(파티션 키 및 정렬 키)은 DynamoDB가 테이블에서 항목을 찾는 데 사용하기 때문에 일반 텍스트로 유지되어야 합니다. 서명은 해야 하지만 암호화해서는 안 됩니다.

 AWS Database Encryption SDK for DynamoDB는 기본 키 속성을 식별하고 값이 서명되었지만 암호화되지 않았는지 확인합니다. 그리고 프라이머리 키를 식별한 다음 암호화하려고 하면 클라이언트에서 예외가 발생합니다.

클라이언트는 항목에 추가하는 새 속성(`aws_dbe_head`)에 [자료 설명](concepts.md#material-description)을 저장합니다. 자료 설명은 항목이 암호화되고 서명된 방법을 설명합니다. 클라이언트는 이 정보를 사용하여 항목을 확인하고 암호를 복호화합니다. 자료 설명을 저장하는 필드는 암호화되지 않습니다.

## 항목에 서명
<a name="sign-the-item"></a>

지정된 속성 값을 암호화한 후 AWS Database Encryption SDK for DynamoDB는 자료 설명, [암호화 컨텍스트](concepts.md#encryption-context) 및 [속성 작업](concepts.md#crypt-actions)`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`에서 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`또는 로 표시된 각 필드의 표준화를 통해 해시 기반 메시지 인증 코드(HMACs)와 [디지털 서명을](concepts.md#digital-sigs) 계산합니다. ECDSA 서명은 기본적으로 활성화되어 있지만 필수는 아닙니다. 클라이언트는 항목에 추가하는 새 속성(`aws_dbe_foot`)에 HMAC와 서명을 저장합니다.

# DynamoDB의 검색 가능한 암호화
<a name="ddb-searchable-encryption"></a>

검색 가능한 암호화를 위해 Amazon DynamoDB 테이블을 구성하려면 [AWS KMS 계층 키링](use-hierarchical-keyring.md)을 사용하여 항목을 보호하는 데 사용되는 데이터 키를 생성, 암호화 및 복호화해야 합니다. 또한 테이블 암호화 구성에 [`SearchConfig`](ddb-net-using.md#ddb-net-search-config)를 포함해야 합니다.

**참고**  
DynamoDB용 Java 클라이언트 측 암호화 라이브러리를 사용하는 경우 DynamoDB API용 하위 수준 AWS Database Encryption SDK를 사용하여 테이블 항목을 암호화, 서명, 확인 및 해독해야 합니다. DynamoDB Enhanced Client와 하위 수준 `DynamoDBItemEncryptor`은 검색 가능한 암호화를 지원하지 않습니다.

**Topics**
+ [비컨을 사용한 보조 인덱스 구성](#ddb-beacon-indexes)
+ [비컨 출력 테스트](#ddb-beacon-testing)

## 비컨을 사용한 보조 인덱스 구성
<a name="ddb-beacon-indexes"></a>

[비컨를 구성한](configure-beacons.md) 후 암호화된 속성을 검색하려면 먼저 각 비컨을 반영하는 보조 인덱스를 구성해야 합니다.

표준 또는 복합 비컨을 구성하면 AWS Database Encryption SDK가 비컨 이름에 `aws_dbe_b_` 접두사를 추가하여 서버가 비컨을 쉽게 식별할 수 있도록 합니다. 예를 들어 복합 비컨 `compoundBeacon`의 이름을 지정하면 실제로는 전체 비컨 이름이 `aws_dbe_b_compoundBeacon`가 됩니다. 표준 또는 복합 비컨을 포함하는 [보조 인덱스](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html)를 구성하려면 비컨 이름을 식별할 때 `aws_dbe_b_` 접두사를 포함해야 합니다.

**파티션 키와 정렬 키**  
프라이머리 키 값은 암호화할 수 없습니다. 파티션 및 정렬 키에 서명해야 합니다. 프라이머리 키 값은 표준 또는 복합 비컨이 될 수 없습니다.  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정`SIGN_ONLY`하지 않는 한 기본 키 값은 이어야 하며, 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.  
프라이머리 키 값은 서명된 비컨일 수 있습니다. 각 프라이머리 키 값에 대해 고유한 서명된 비컨을 구성한 경우 프라이머리 키 값을 서명된 비컨 이름으로 식별하는 속성 이름을 지정해야 합니다. 그러나 AWS Database Encryption SDK는 서명된 비컨에 `aws_dbe_b_` 접두사를 추가하지 않습니다. 프라이머리 키 값에 대해 고유한 서명된 비컨를 구성한 경우에도 보조 인덱스를 구성할 때 프라이머리 키 값의 속성 이름만 지정하면 됩니다.

**로컬 보조 인덱스**  
[로컬 보조 인덱스](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html)의 정렬 키는 비컨일 수 있습니다.  
정렬 키에 비컨를 지정하는 경우 유형은 문자열이어야 합니다. 정렬 키에 표준 또는 복합 비컨를 지정하는 경우 비컨 이름을 지정할 때 `aws_dbe_b_` 접두사를 포함해야 합니다. 서명된 비컨를 지정하는 경우 접두사 없이 비컨 이름을 지정합니다.

**글로벌 보조 인덱스**  
[글로벌 보조 인덱스](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html)의 파티션 키와 정렬 키는 모두 비컨일 수 있습니다.  
파티션이나 정렬 키에 비컨을 지정하는 경우 유형은 문자열이어야 합니다. 정렬 키에 표준 또는 복합 비컨를 지정하는 경우 비컨 이름을 지정할 때 `aws_dbe_b_` 접두사를 포함해야 합니다. 서명된 비컨를 지정하는 경우 접두사 없이 비컨 이름을 지정합니다.

**속성 프로젝션**  
[프로젝션](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.Projections)은 테이블에서 보조 인덱스로 복사되는 속성 집합입니다. 테이블의 파티션 키와 정렬 키는 항상 인덱스로 프로젝션되지만, 다른 속성을 프로젝션하여 애플리케이션의 쿼리 요건을 지원하는 것도 가능합니다. DynamoDB는 속성 프로젝션을 위한 세 가지 옵션(`KEYS_ONLY`, `INCLUDE`, 및 `ALL`)을 제공합니다.  
INCLUDE 속성 프로젝션을 사용하여 비컨을 검색하는 경우 비컨을 구성하는 모든 속성의 이름과 `aws_dbe_b_` 접두사를 포함한 비컨 이름을 지정해야 합니다. 예를 들어 `field1`, `field2`, 및 `field3`에서 복합 비콘 `compoundBeacon`을 구성한 경우 프로젝션에서 `aws_dbe_b_compoundBeacon`, `field1`, `field2`, 및 `field3`를 지정해야 합니다.  
글로벌 보조 인덱스는 프로젝션에 명시적으로 지정된 속성만 사용할 수 있지만 로컬 보조 인덱스는 모든 속성을 사용할 수 있습니다.

## 비컨 출력 테스트
<a name="ddb-beacon-testing"></a>

[복합 비컨을 구성](configure-beacons.md#config-compound-beacons)하거나 [가상 필드를](configure-beacons.md#create-virtual-field) 사용하여 비컨을 구성한 경우 DynamoDB 테이블을 채우기 전에 이러한 비컨이 예상 출력을 생성하는지 확인하는 것이 좋습니다.

 AWS Database Encryption SDK는 가상 필드 및 복합 비컨 출력 문제를 해결하는 데 도움이 되는 `DynamoDbEncryptionTransforms` 서비스를 제공합니다.

### 가상 필드 테스트
<a name="ddb-beacon-testing-virtual-field"></a>

다음 코드 조각은 테스트 항목을 생성하고, [DynamoDB 테이블 암호화 구성](ddb-java-using.md#ddb-config-encrypt)으로 `DynamoDbEncryptionTransforms` 서비스를 정의하고,를 사용하여 가상 필드가 예상 출력을 생성하는지 `ResolveAttributes` 확인하는 방법을 보여줍니다.

------
#### [ Java ]

**전체 코드 샘플**: [VirtualBeaconSearchableEncryptionExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/VirtualBeaconSearchableEncryptionExample.java) 참조 

```
// Create test items
final PutItemRequest itemWithHasTestResultPutRequest = PutItemRequest.builder()
    .tableName(ddbTableName)
    .item(itemWithHasTestResult)
    .build();

final PutItemResponse itemWithHasTestResultPutResponse = ddb.putItem(itemWithHasTestResultPutRequest);

final PutItemRequest itemWithNoHasTestResultPutRequest = PutItemRequest.builder()
    .tableName(ddbTableName)
    .item(itemWithNoHasTestResult)
    .build();
    
final PutItemResponse itemWithNoHasTestResultPutResponse = ddb.putItem(itemWithNoHasTestResultPutRequest);    

// Define the DynamoDbEncryptionTransforms service
final DynamoDbEncryptionTransforms trans = DynamoDbEncryptionTransforms.builder()
    .DynamoDbTablesEncryptionConfig(encryptionConfig).build();

// Verify configuration
final ResolveAttributesInput resolveInput = ResolveAttributesInput.builder()
    .TableName(ddbTableName)
    .Item(itemWithHasTestResult)
    .Version(1)
    .build();
final ResolveAttributesOutput resolveOutput = trans.ResolveAttributes(resolveInput);

// Verify that VirtualFields has the expected value
Map<String, String> vf = new HashMap<>();
vf.put("stateAndHasTestResult", "CAt");
assert resolveOutput.VirtualFields().equals(vf);
```

------
#### [ C\$1 / .NET ]

**전체 코드 샘플: VirtualBeaconSearchableEncryptionExample.cs를 참조**하세요. [VirtualBeaconSearchableEncryptionExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/searchableencryption/VirtualBeaconSearchableEncryptionExample.cs)

```
 // Create item with hasTestResult=true
var itemWithHasTestResult = new Dictionary<String, AttributeValue>
{
    ["customer_id"] = new AttributeValue("ABC-123"),
    ["create_time"] = new AttributeValue { N = "1681495205" },
    ["state"] = new AttributeValue("CA"),
    ["hasTestResult"] = new AttributeValue { BOOL = true }
};

// Create item with hasTestResult=false
var itemWithNoHasTestResult = new Dictionary<String, AttributeValue>
{
    ["customer_id"] = new AttributeValue("DEF-456"),
    ["create_time"] = new AttributeValue { N = "1681495205" },
    ["state"] = new AttributeValue("CA"),
    ["hasTestResult"] = new AttributeValue { BOOL = false }
};

// Define the DynamoDbEncryptionTransforms service
var trans = new DynamoDbEncryptionTransforms(encryptionConfig);

// Verify configuration
var resolveInput = new ResolveAttributesInput
{
    TableName = ddbTableName,
    Item = itemWithHasTestResult,
    Version = 1
};
var resolveOutput = trans.ResolveAttributes(resolveInput);

// Verify that VirtualFields has the expected value
Debug.Assert(resolveOutput.VirtualFields.Count == 1);
Debug.Assert(resolveOutput.VirtualFields["stateAndHasTestResult"] == "CAt");
```

------
#### [ Rust ]

**전체 코드 샘플: virtual\$1beacon\$1searchable\$1encryption.rs를 참조**하세요. [https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/virtual_beacon_searchable_encryption.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/virtual_beacon_searchable_encryption.rs) 

```
// Create item with hasTestResult=true
let item_with_has_test_result = HashMap::from([
    (
        "customer_id".to_string(),
        AttributeValue::S("ABC-123".to_string()),
    ),
    (
        "create_time".to_string(),
        AttributeValue::N("1681495205".to_string()),
    ),
    ("state".to_string(), AttributeValue::S("CA".to_string())),
    ("hasTestResult".to_string(), AttributeValue::Bool(true)),
]);

// Create item with hasTestResult=false
let item_with_no_has_test_result = HashMap::from([
    (
        "customer_id".to_string(),
        AttributeValue::S("DEF-456".to_string()),
    ),
    (
        "create_time".to_string(),
        AttributeValue::N("1681495205".to_string()),
    ),
    ("state".to_string(), AttributeValue::S("CA".to_string())),
    ("hasTestResult".to_string(), AttributeValue::Bool(false)),
]);

// Define the transform service
let trans = transform_client::Client::from_conf(encryption_config.clone())?;

// Verify the configuration 
let resolve_output = trans
    .resolve_attributes()
    .table_name(ddb_table_name)
    .item(item_with_has_test_result.clone())
    .version(1)
    .send()
    .await?;

// Verify that VirtualFields has the expected value
let virtual_fields = resolve_output.virtual_fields.unwrap();
assert_eq!(virtual_fields.len(), 1);
assert_eq!(virtual_fields["stateAndHasTestResult"], "CAt");
```

------

### 복합 비컨 테스트
<a name="ddb-beacon-testing-compound-beacon"></a>

다음 코드 조각은 테스트 항목을 생성하고, [DynamoDB 테이블 암호화 구성](ddb-java-using.md#ddb-config-encrypt)으로 `DynamoDbEncryptionTransforms` 서비스를 정의하고,를 `ResolveAttributes` 사용하여 복합 비컨이 예상 출력을 생성하는지 확인하는 방법을 보여줍니다.

------
#### [ Java ]

**전체 코드 샘플**: [CompoundBeaconSearchableEncryptionExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/CompoundBeaconSearchableEncryptionExample.java) 참조 

```
// Create an item with both attributes used in the compound beacon.
final HashMap<String, AttributeValue> item = new HashMap<>();
item.put("work_id", AttributeValue.builder().s("9ce39272-8068-4efd-a211-cd162ad65d4c").build());
item.put("inspection_date", AttributeValue.builder().s("2023-06-13").build());
item.put("inspector_id_last4", AttributeValue.builder().s("5678").build());
item.put("unit", AttributeValue.builder().s("011899988199").build());
                            
// Define the DynamoDbEncryptionTransforms service
final DynamoDbEncryptionTransforms trans = DynamoDbEncryptionTransforms.builder()
    .DynamoDbTablesEncryptionConfig(encryptionConfig).build();

// Verify configuration 
final ResolveAttributesInput resolveInput = ResolveAttributesInput.builder()
    .TableName(ddbTableName)
    .Item(item)
    .Version(1)
    .build();

final ResolveAttributesOutput resolveOutput = trans.ResolveAttributes(resolveInput);
                            
// Verify that CompoundBeacons has the expected value   
Map<String, String> cbs = new HashMap<>();
cbs.put("last4UnitCompound", "L-5678.U-011899988199");
assert resolveOutput.CompoundBeacons().equals(cbs);
// Note : the compound beacon actually stored in the table is not "L-5678.U-011899988199"
// but rather something like "L-abc.U-123", as both parts are EncryptedParts
// and therefore the text is replaced by the associated beacon
```

------
#### [ C\$1 / .NET ]

**전체 코드 샘플**: [CompoundBeaconSearchableEncryptionExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/searchableencryption/CompoundBeaconSearchableEncryptionExample.cs) 참조

```
// Create an item with both attributes used in the compound beacon
var item = new Dictionary<String, AttributeValue>
{
    ["work_id"] = new AttributeValue("9ce39272-8068-4efd-a211-cd162ad65d4c"),
    ["inspection_date"] = new AttributeValue("2023-06-13"),
    ["inspector_id_last4"] = new AttributeValue("5678"),
    ["unit"] = new AttributeValue("011899988199")
};                           
                            
// Define the DynamoDbEncryptionTransforms service
var trans = new DynamoDbEncryptionTransforms(encryptionConfig);

// Verify configuration
var resolveInput = new ResolveAttributesInput
{
    TableName = ddbTableName,
    Item = item,
    Version = 1
};
var resolveOutput = trans.ResolveAttributes(resolveInput);                            
                            
// Verify that CompoundBeacons has the expected value 
Debug.Assert(resolveOutput.CompoundBeacons.Count == 1);
Debug.Assert(resolveOutput.CompoundBeacons["last4UnitCompound"] == "L-5678.U-011899988199");
// Note : the compound beacon actually stored in the table is not "L-5678.U-011899988199"
// but rather something like "L-abc.U-123", as both parts are EncryptedParts
// and therefore the text is replaced by the associated beacon
```

------
#### [ Rust ]

**전체 코드 샘플: compound\$1beacon\$1searchable\$1encryption.rs를 참조하세요**. [https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/compound_beacon_searchable_encryption.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/compound_beacon_searchable_encryption.rs) 

```
// Create an item with both attributes used in the compound beacon
let item = HashMap::from([
    (
        "work_id".to_string(),
        AttributeValue::S("9ce39272-8068-4efd-a211-cd162ad65d4c".to_string()),
    ),
    (
        "inspection_date".to_string(),
        AttributeValue::S("2023-06-13".to_string()),
    ),
    (
        "inspector_id_last4".to_string(),
        AttributeValue::S("5678".to_string()),
    ),
    (
        "unit".to_string(),
        AttributeValue::S("011899988199".to_string()),
    ),
]);                           
                            
// Define the transforms service
let trans = transform_client::Client::from_conf(encryption_config.clone())?;

// Verify configuration
let resolve_output = trans
    .resolve_attributes()
    .table_name(ddb_table_name)
    .item(item.clone())
    .version(1)
    .send()
    .await?;                            
                            
// Verify that CompoundBeacons has the expected value 
let compound_beacons = resolve_output.compound_beacons.unwrap();
assert_eq!(compound_beacons.len(), 1);
assert_eq!(
    compound_beacons["last4UnitCompound"],
    "L-5678.U-011899988199"
);
// but rather something like "L-abc.U-123", as both parts are EncryptedParts
// and therefore the text is replaced by the associated beacon
```

------

# 데이터 모델 업데이트
<a name="ddb-update-data-model"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

DynamoDB용 AWS Database Encryption SDK를 구성할 때 [속성 작업을](concepts.md#crypt-actions) 제공합니다. 암호화 시 AWS 데이터베이스 암호화 SDK는 속성 작업을 사용하여 암호화 및 서명할 속성, 서명할 속성(암호화하지 않음), 무시할 속성을 식별합니다. 또한 서명에서 제외되는 속성을 클라이언트에게 명시적으로 알리도록 [허용된 무서명 속성](ddb-java-using.md#allowed-unauth)을 정의합니다. 복호화 시 AWS Database Encryption SDK는 사용자가 정의한 허용된 서명되지 않은 속성을 사용하여 서명에 포함되지 않은 속성을 식별합니다. 속성 작업은 암호화된 항목에 저장되지 않으며 AWS Database Encryption SDK는 속성 작업을 자동으로 업데이트하지 않습니다.

속성 작업을 신중하게 선택합니다. 확실하지 않은 경우 **Encrypt and sign(암호화 및 서명)**을 사용합니다. AWS Database Encryption SDK를 사용하여 항목을 보호한 후에는 기존 , `ENCRYPT_AND_SIGN` `SIGN_ONLY`또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 로 변경할 수 없습니다`DO_NOTHING`. 그러나 다음과 같이 안전하게 변경할 수 있습니다.
+ [새 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`및 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성 추가](#ddb-add-auth-attribute)
+ [기존 속성 제거](#ddb-remove-attribute)
+ [기존 `ENCRYPT_AND_SIGN` 속성을 `SIGN_ONLY` 또는 로 변경 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`](#ddb-encrypt-to-sign)
+ [기존 `SIGN_ONLY` 또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 로 변경 `ENCRYPT_AND_SIGN`](#ddb-sign-to-encrypt)
+ [새 `DO_NOTHING` 속성 추가](#ddb-add-unauth-attribute)
+ [기존 `SIGN_ONLY` 속성을 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`로 변경합니다.](#ddb-signOnly-to-signInclude)
+ [기존 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 `SIGN_ONLY`로 변경합니다.](#ddb-signInclude-to-signOnly)

**검색 가능한 암호화에 대한 고려 사항**  
데이터 모델을 업데이트하기 전에 업데이트가 속성으로 구성한 모든 [비컨](beacons.md)에 어떤 영향을 미칠 수 있는지 신중하게 고려해야 합니다. 비컨으로 새 레코드를 작성한 후에는 비컨의 구성을 업데이트할 수 없습니다. 비컨을 구성하는 데 사용한 속성과 관련된 속성 작업은 업데이트할 수 없습니다. 기존 속성 및 관련 비컨을 제거하면 해당 비컨을 사용하여 기존 레코드를 쿼리할 수 없습니다. 레코드에 추가하는 새 필드에 대해 새 비컨을 만들 수 있지만 새 필드를 포함하도록 기존 비컨을 업데이트할 수는 없습니다.

**`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성에 대한 고려 사항**  
기본적으로 파티션 및 정렬 키는 암호화 컨텍스트에 포함된 유일한 속성입니다. [AWS KMS 계층적 키링](use-hierarchical-keyring.md)의 브랜치 키 ID 공급자가 암호화 컨텍스트에서 복호화하는 데 필요한 브랜치 키를 식별할 수 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 있도록 추가 필드를 로 정의하는 것이 좋습니다. 자세한 내용은 [브랜치 키 ID 공급자](use-hierarchical-keyring.md#branch-key-id-supplier)를 참조하세요. `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

**참고**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 암호화 작업을 사용하려면 AWS Database Encryption SDK 버전 3.3 이상을 사용해야 합니다. 를 포함하도록 [데이터 모델을 업데이트하기 전에 모든 리더](#ddb-update-data-model)에 새 버전을 배포합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

## 새 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`및 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성 추가
<a name="ddb-add-auth-attribute"></a>

새 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 추가하려면 속성 작업에서 새 속성을 정의합니다.

기존 `DO_NOTHING` 속성을 제거하고 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성으로 다시 추가할 수 없습니다.

**주석이 달린 데이터 클래스 사용**  
`TableSchema`를 사용하여 속성 작업을 정의한 경우 주석이 달린 데이터 클래스에 새 속성을 추가합니다. 새 속성에 속성 작업 주석을 지정하지 않으면 클라이언트는 기본적으로 새 속성을 암호화하고 서명합니다(속성이 프라이머리 키의 일부가 아닌 경우). 새 속성에만 서명하려면 `@DynamoDBEncryptionSignOnly` 또는 `@DynamoDBEncryptionSignAndIncludeInEncryptionContext` 주석을 사용하여 새 속성을 추가해야 합니다.

**객체 모델 사용**  
속성 작업을 수동으로 정의한 경우 객체 모델의 속성 작업에 새 속성을 추가하고 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`또는를 속성 작업`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`으로 지정합니다.

## 기존 속성 제거
<a name="ddb-remove-attribute"></a>

속성이 더 이상 필요하지 않다고 판단되면 해당 속성에 데이터 쓰기를 중단하거나 속성 작업에서 해당 속성을 공식적으로 제거할 수 있습니다. 속성에 새 데이터 쓰기를 중지해도 해당 속성은 여전히 속성 작업에 표시됩니다. 이는 나중에 속성 사용을 다시 시작해야 하는 경우에 유용할 수 있습니다. 속성 작업에서 속성을 정식으로 제거해도 데이터 세트에서 제거되지는 않습니다. 데이터 세트에는 해당 속성이 포함된 항목이 계속 포함됩니다.

기존 `ENCRYPT_AND_SIGN`, `SIGN_ONLY``SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`, 또는 `DO_NOTHING` 속성을 공식적으로 제거하려면 속성 작업을 업데이트합니다.

`DO_NOTHING` 속성을 제거하는 경우 [허용된 무서명 속성](ddb-java-using.md#allowed-unauth)에서 해당 속성을 제거해서는 안 됩니다. 더 이상 해당 속성에 새 값을 쓰지 않아도 클라이언트가 속성이 포함된 기존 항목을 읽으려면 속성이 서명되지 않았음을 알아야 합니다.

**주석이 달린 데이터 클래스 사용**  
`TableSchema`를 사용하여 속성 작업을 정의한 경우 주석이 달린 데이터 클래스에서 해당 속성을 제거합니다.

**객체 모델 사용**  
속성 동작을 수동으로 정의한 경우 객체 모델의 속성 작업에서 속성을 제거합니다.

## 기존 `ENCRYPT_AND_SIGN` 속성을 `SIGN_ONLY` 또는 로 변경 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`
<a name="ddb-encrypt-to-sign"></a>

기존 `ENCRYPT_AND_SIGN` 속성을 `SIGN_ONLY` 또는 로 변경하려면 속성 작업을 업데이트`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`해야 합니다. 업데이트를 배포한 후 클라이언트는 속성에 레코드된 기존 값을 확인하고 복호화할 수 있지만 속성에 기록된 새 값에만 서명합니다.

**참고**  
기존 `ENCRYPT_AND_SIGN` 속성을 `SIGN_ONLY` 또는 로 변경하기 전에 보안 요구 사항을 신중하게 고려하세요`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. 민감한 데이터를 저장할 수 있는 모든 속성은 암호화되어야 합니다.

**주석이 달린 데이터 클래스 사용**  
를 사용하여 속성 작업을 정의한 경우 주석이 달린 데이터 클래스에 `@DynamoDBEncryptionSignOnly` 또는 `@DynamoDBEncryptionSignAndIncludeInEncryptionContext` 주석을 포함하도록 기존 속성을 `TableSchema`업데이트합니다.

**객체 모델 사용**  
속성 작업을 수동으로 정의한 경우 객체 모델에서 기존 속성과 연결된 속성 작업을에서 `SIGN_ONLY` 또는 `ENCRYPT_AND_SIGN` 로 업데이트`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`합니다.

## 기존 `SIGN_ONLY` 또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 로 변경 `ENCRYPT_AND_SIGN`
<a name="ddb-sign-to-encrypt"></a>

기존 `SIGN_ONLY` 또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 로 변경하려면 속성 작업을 업데이트`ENCRYPT_AND_SIGN`해야 합니다. 업데이트를 배포한 후 클라이언트는 속성에 레코드된 기존 값을 확인하고 속성에 기록된 새 값을 암호화하고 서명할 수 있습니다.

**주석이 달린 데이터 클래스 사용**  
를 사용하여 속성 작업을 정의한 경우 기존 속성에서 `@DynamoDBEncryptionSignOnly` 또는 `@DynamoDBEncryptionSignAndIncludeInEncryptionContext` 주석을 `TableSchema`제거합니다.

**객체 모델 사용**  
속성 작업을 수동으로 정의한 경우 객체 모델의 `SIGN_ONLY` 또는 `ENCRYPT_AND_SIGN`에서 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`로 속성과 연결된 속성 작업을 업데이트합니다.

## 새 `DO_NOTHING` 속성 추가
<a name="ddb-add-unauth-attribute"></a>

새 `DO_NOTHING` 속성을 추가할 때 오류가 발생할 위험을 줄이려면 `DO_NOTHING` 속성의 이름을 지정할 때 고유한 접두사를 지정한 다음 해당 접두사를 사용하여 [허용되는 무서명 속성](ddb-java-using.md#allowed-unauth)을 정의하는 것이 좋습니다.

주석이 달린 데이터 클래스에서 기존 `ENCRYPT_AND_SIGN``SIGN_ONLY`, 또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 제거한 다음 속성을 속성으로 다시 추가할 수 없습니다`DO_NOTHING`. 완전히 새로운 `DO_NOTHING` 속성만 추가할 수 있습니다.

새 `DO_NOTHING` 속성을 추가하는 단계는 허용된 서명되지 않은 속성을 목록에 명시적으로 정의했는지 아니면 접두사를 사용하여 정의했는지에 따라 달라집니다.

**허용된 무서명 속성 접두사 사용**  
`TableSchema`을 사용하여 속성 작업을 정의한 경우 `@DynamoDBEncryptionDoNothing` 주석을 사용하여 주석이 달린 데이터 클래스에 새 `DO_NOTHING` 속성을 추가합니다. 속성 작업을 수동으로 정의한 경우 새 속성을 포함하도록 속성 작업을 업데이트합니다. `DO_NOTHING` 속성 작업을 사용하여 새 속성을 명시적으로 구성해야 합니다. 새 속성 이름에 동일한 고유 접두사를 포함해야 합니다.

**허용된 무서명 속성 목록 사용**

1. 허용된 무서명 속성 목록에 새 `DO_NOTHING` 속성을 추가하고 업데이트된 목록을 배포합니다.

1. **1단계**에서 변경한 내용을 배포합니다.

   이 데이터를 읽어야 하는 모든 호스트에 변경 내용이 전파되기 전까지는 **3단계**로 넘어갈 수 없습니다.

1. 새 `DO_NOTHING` 속성을 속성 작업에 추가합니다.

   1. `TableSchema`을 사용하여 속성 작업을 정의한 경우 `@DynamoDBEncryptionDoNothing` 주석을 사용하여 주석이 달린 데이터 클래스에 새 `DO_NOTHING` 속성을 추가합니다.

   1. 속성 작업을 수동으로 정의한 경우 새 속성을 포함하도록 속성 작업을 업데이트합니다. `DO_NOTHING` 속성 작업을 사용하여 새 속성을 명시적으로 구성해야 합니다.

1. **3단계**에서 변경한 내용을 배포합니다.

## 기존 `SIGN_ONLY` 속성을 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`로 변경합니다.
<a name="ddb-signOnly-to-signInclude"></a>

기존 `SIGN_ONLY` 속성을 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`로 변경하려면 속성 작업을 업데이트해야 합니다. 업데이트를 배포한 후 클라이언트는 속성에 기록된 기존 값을 확인할 수 있으며 속성에 기록된 새 값에 계속 서명합니다. 속성에 기록된 새 값은 [암호화 컨텍스트](concepts.md#encryption-context)에 포함됩니다.

`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

**주석이 달린 데이터 클래스 사용**  
를 사용하여 속성 작업을 정의한 경우 속성과 연결된 속성 작업을에서 로 `TableSchema`업데이트`@DynamoDBEncryptionSignOnly`합니다`@DynamoDBEncryptionSignAndIncludeInEncryptionContext`.

**객체 모델 사용**  
속성 작업을 수동으로 정의한 경우, 객체 모델에서 속성과 연관된 속성 작업을 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 에서 `SIGN_ONLY` 로 업데이트합니다.

## 기존 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 `SIGN_ONLY`로 변경합니다.
<a name="ddb-signInclude-to-signOnly"></a>

기존 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 `SIGN_ONLY`로 변경하려면 속성 작업을 업데이트해야 합니다. 업데이트를 배포한 후 클라이언트는 속성에 기록된 기존 값을 확인할 수 있으며 속성에 기록된 새 값에 계속 서명합니다. 속성에 기록된 새 값은 [암호화 컨텍스트](concepts.md#encryption-context)에 포함되지 않습니다.

기존 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 로 변경하기 전에 업데이트가 [브랜치 키 ID 공급자](use-hierarchical-keyring.md#branch-key-id-supplier)의 기능에 어떤 영향을 미칠 수 있는지 `SIGN_ONLY`신중하게 고려하세요.

**주석이 달린 데이터 클래스 사용**  
를 사용하여 속성 작업을 정의한 경우 속성과 연결된 속성 작업을에서 로 `TableSchema`업데이트`@DynamoDBEncryptionSignAndIncludeInEncryptionContext`합니다`@DynamoDBEncryptionSignOnly`.

**객체 모델 사용**  
속성 작업을 수동으로 정의한 경우, 객체 모델에서 속성과 연관된 속성 작업을 `SIGN_ONLY` 에서 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 로 업데이트합니다.

# AWS Database Encryption SDK for DynamoDB 사용 가능한 프로그래밍 언어
<a name="ddb-programming-languages"></a>

DynamoDB용 AWS Database Encryption SDK는 다음 프로그래밍 언어에 사용할 수 있습니다. 언어별 라이브러리는 다양하지만 결과 구현은 상호 운용이 가능합니다. 하나의 언어 구현으로 암호화하고 다른 언어 구현으로 복호화할 수 있습니다. 상호 연동성에는 언어 제약 조건이 적용될 수 있습니다. 이 경우 이러한 제약 조건은 언어 구현에 대한 주제에 설명되어 있습니다.

**Topics**
+ [Java](ddb-java.md)
+ [.NET](ddb-net.md)
+ [Rust](ddb-rust.md)

# Java
<a name="ddb-java"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

이 주제에서는 DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*를 설치하고 사용하는 방법을 설명합니다. DynamoDB용 AWS Database Encryption SDK를 사용한 프로그래밍에 대한 자세한 내용은 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에서 [Java 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples)를 참조하세요.

**참고**  
다음 주제에서는 DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*에 중점을 둡니다.  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). AWS Database Encryption SDK는 [레거시 DynamoDB Encryption Client 버전을](legacy-dynamodb-encryption-client.md) 계속 지원합니다.

**Topics**
+ [사전 조건](#ddb-java-prerequisites)
+ [설치](#ddb-java-installation)
+ [Java 클라이언트 사용](ddb-java-using.md)
+ [Java 예제](ddb-java-examples.md)
+ [기존 테이블에 버전 3.x 추가](ddb-java-config-existing-table.md)
+ [버전 3.x로 마이그레이션](ddb-java-migrate.md)

## 사전 조건
<a name="ddb-java-prerequisites"></a>

버전 3.*x*을 설치하기 전에 DynamoDB용 Java 클라이언트측 암호화 라이브러리의 경우 다음과 같은 사전 요구 사항이 있는지 확인합니다.

**Java 개발 환경**  
Java 8 이상이 필요합니다. Oracle 웹 사이트에서 [Java SE 다운로드](https://www.oracle.com/java/technologies/downloads/)로 이동한 다음 Java SE Development Kit(JDK)를 다운로드하여 설치합니다.  
Oracle JDK를 사용하는 경우 [Java Cryptography Extension(JCE) Unlimited Strength Jurisdiction Policy File](http://www.oracle.com/java/technologies/javase-jce8-downloads.html)도 다운로드하여 설치해야 합니다.

**AWS SDK for Java 2.x**  
 AWS Database Encryption SDK for DynamoDB에는의 [DynamoDB 향상된 클라이언트](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) 모듈이 필요합니다 AWS SDK for Java 2.x. 전체 SDK를 설치하거나 이 모듈만 설치할 수 있습니다.  
버전 업데이트에 대한 자세한 내용은의 버전 1.x에서 2.x로 마이그레이션을 AWS SDK for Java참조하세요. [AWS SDK for Java](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html)   
 AWS SDK for Java 는 Apache Maven을 통해 사용할 수 있습니다. 전체 AWS SDK for Java또는 `dynamodb-enhanced` 모듈에 대한 종속성을 선언할 수 있습니다.  

**Apache Maven을 AWS SDK for Java 사용하여 설치**
+ [전체 AWS SDK for Java를 종속성으로 가져오려면](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#build-the-entire-sdk-into-your-project) `pom.xml` 파일에 선언하세요.
+  AWS SDK for Java에서 Amazon DynamoDB 모듈에 대해서만 종속성을 생성하려면 [특정 모듈을 지정](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#modules-dependencies)하는 지침을 따릅니다. `groupId`를 `software.amazon.awssdk`로, `artifactID`를 `dynamodb-enhanced`로 설정합니다.
**참고**  
 AWS KMS 키링 또는 AWS KMS 계층적 키링을 사용하는 경우 AWS KMS 모듈에 대한 종속성도 생성해야 합니다. `groupId`를 `software.amazon.awssdk`로, `artifactID`를 `kms`로 설정합니다.

## 설치
<a name="ddb-java-installation"></a>

다음 방법으로 DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*를 설치할 수 있습니다.

**Apache Maven 사용**  
Amazon DynamoDB Encryption Client for Java는 다음 종속성 정의와 함께 [Apache Maven](https://maven.apache.org/)을 통해 사용할 수 있습니다.  

```
<dependency>
  <groupId>software.amazon.cryptography</groupId>
  <artifactId>aws-database-encryption-sdk-dynamodb</artifactId>
  <version>version-number</version>
</dependency>
```

**Gradle Kotlin 사용**  
[Gradle](https://gradle.org/)을 사용하면 Gradle 프로젝트의 *종속성* 섹션에 다음을 추가하여 Java용 Amazon DynamoDB Encryption Client에 대한 종속성을 선언할 수 있습니다.  

```
implementation("software.amazon.cryptography:aws-database-encryption-sdk-dynamodb:version-number")
```

**직접**  
DynamoDB용 Java 클라이언트 측 암호화 라이브러리를 설치하려면 [aws-database-encryption-sdk-dynamodb](https://github.com/aws/aws-database-encryption-sdk-dynamodb/) GitHub 리포지토리를 복제하거나 다운로드합니다.

SDK를 설치한 후이 가이드의 예제 코드와 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에 있는 [Java 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples)를 살펴보면서 시작합니다.

# DynamoDB용 Java 클라이언트측 암호화 라이브러리 사용
<a name="ddb-java-using"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

이 주제에서는 DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*의 일부 기능과 헬퍼 클래스에 대해 설명합니다.

DynamoDB용 Java 클라이언트 측 암호화 라이브러리를 사용한 프로그래밍에 대한 자세한 내용은 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에 있는 [Java 예제](java-examples.md)인 [Java 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples)를 참조하세요.

**Topics**
+ [항목 암호화 도구](#ddb-item-encryptors)
+ [속성 작업](#ddb-attribute-actions)
+ [암호화 구성](#ddb-config-encrypt)
+ [항목 업데이트](#ddb-update-items)
+ [서명된 집합 암호 해독](#ddb-java-signed-sets)

## 항목 암호화 도구
<a name="ddb-item-encryptors"></a>

코어에서 AWS Database Encryption SDK for DynamoDB는 항목 암호화 도구입니다. DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x* 를 사용하여 다음과 같은 방법으로 DynamoDB 테이블 항목을 암호화, 서명, 확인 및 복호화할 수 있습니다.

**DynamoDB Enhanced Client**  
`DynamoDbEncryptionInterceptor`를 사용하여 DynamoDB `PutItem` 요청에 따라 클라이언트측에서 항목을 자동으로 암호화하고 서명하도록 [DynamoDB Enhanced Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html)를 구성할 수 있습니다. DynamoDB Enhanced Client에서는 [주석이 달린 데이터 클래스](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html#ddb-en-client-gs-tableschema-anno-bean)를 사용하여 속성 작업을 정의할 수 있습니다. 가능하면 DynamoDB Enhanced Client를 사용하는 것이 좋습니다.  
DynamoDB Enhanced Client는 [검색 가능한 암호화](searchable-encryption.md)를 지원하지 않습니다.  
 AWS Database Encryption SDK는 [중첩 속성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-adv-features-nested.html)에 대한 주석을 지원하지 않습니다.

**하위 수준 DynamoDB API**  
`DynamoDbEncryptionInterceptor`를 사용하여 DynamoDB `PutItem` 요청에 따라 클라이언트측에서 항목을 자동으로 암호화하고 서명하도록 [하위 수준 DynamoDB API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html)를 구성할 수 있습니다.  
[검색 가능한 암호화](searchable-encryption.md)를 사용하려면 하위 수준 DynamoDB API를 사용해야 합니다.

**하위 수준 `DynamoDbItemEncryptor`**  
하위 수준 `DynamoDbItemEncryptor`에서는 DynamoDB를 호출하지 않고도 테이블 항목을 직접 암호화하고 서명 또는 복호화하고 확인합니다. DynamoDB `PutItem` 또는 `GetItem` 요청을 하지 않습니다. 예를 들어 하위 수준 `DynamoDbItemEncryptor`을 사용하여 이미 검색한 DynamoDB 항목을 직접 복호화하고 확인할 수 있습니다.  
하위 수준 `DynamoDbItemEncryptor`은 [검색 가능한 암호화](searchable-encryption.md)를 지원하지 않습니다.

## AWS Database Encryption SDK for DynamoDB의 속성 작업
<a name="ddb-attribute-actions"></a>

[속성 작업은](concepts.md#crypt-actions) 암호화 및 서명되는 속성 값, 서명만 되는 속성 값, 암호화 컨텍스트에 서명 및 포함되는 속성 값, 무시되는 속성 값을 결정합니다.

**참고**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 암호화 작업을 사용하려면 AWS Database Encryption SDK 버전 3.3 이상을 사용해야 합니다. 를 포함하도록 [데이터 모델을 업데이트하기 전에 모든 리더](ddb-update-data-model.md)에 새 버전을 배포합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

하위 수준 DynamoDB API 또는 하위 수준 `DynamoDbItemEncryptor`을 사용하는 경우 속성 작업을 수동으로 정의해야 합니다. DynamoDB Enhanced Client를 사용하는 경우 속성 작업을 수동으로 정의하거나 주석이 달린 데이터 클래스를 사용하여 [`TableSchema`을 생성할 수 있습니다](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html). 구성 프로세스를 단순화하려면 주석이 달린 데이터 클래스를 사용하는 것이 좋습니다. 주석이 달린 데이터 클래스를 사용하는 경우 객체를 한 번만 모델링하면 됩니다.

**참고**  
속성 작업을 정의한 후에는 서명에서 제외할 속성을 정의해야 합니다. 나중에 서명되지 않은 새 속성을 더 쉽게 추가할 수 있도록 서명되지 않은 속성을 식별할 고유한 접두사(예: "`:`“)를 선택하는 것이 좋습니다. DynamoDB 스키마와 속성 작업을 정의할 때 `DO_NOTHING`로 표시된 모든 속성의 속성 이름에 이 접두사를 포함합니다.

### 주석이 달린 데이터 클래스 사용
<a name="ddb-attribute-actions-annotated-data-class"></a>

[주석이 달린 데이터 클래스](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html#ddb-en-client-gs-tableschema-anno-bean)를 사용하여 DynamoDB Enhanced Client 및 `DynamoDbEncryptionInterceptor`에서 속성 작업을 지정합니다. AWS Database Encryption SDK for DynamoDB는 속성 유형을 정의하는 [표준 DynamoDB 속성 주석](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/package-summary.html)을 사용하여 속성을 보호하는 방법을 결정합니다. 기본적으로 기본 키(서명되지만 암호화되지 않음)를 제외하고는 모든 속성이 암호화 및 서명됩니다.

**참고**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 암호화 작업을 사용하려면 AWS Database Encryption SDK 버전 3.3 이상을 사용해야 합니다. 를 포함하도록 [데이터 모델을 업데이트하기 전에 모든 리더](ddb-update-data-model.md)에 새 버전을 배포합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

DynamoDB 향상된 클라이언트 주석에 대한 자세한 지침은 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에서 [SimpleClass.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/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 Database Encryption SDK는 [중첩 속성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-adv-features-nested.html)에 대한 주석을 지원하지 않습니다.

다음 예제에서는 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`및 `DO_NOTHING`속성 작업을 정의하는 데 사용되는 주석을 보여줍니다. 를 정의하는 데 사용되는 주석을 보여주는 예제는 [SimpleClass4.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/SimpleClass4.java)를 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`참조하세요.

```
@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);
```

### 속성 작업 수동 정의
<a name="ddb-attribute-actions-manual"></a>

속성 작업을 수동으로 지정하려면 이름-값 페어가 속성 이름과 지정된 작업을 나타내는 `Map` 객체를 만듭니다.

속성을 암호화하고 서명하도록 `ENCRYPT_AND_SIGN`을 지정합니다. 속성을 서명하되 암호화하지 않도록 `SIGN_ONLY`을 지정합니다. 를 지정`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`하여 속성에 서명하고 암호화 컨텍스트에 포함합니다. 서명하지 않으면 속성을 암호화할 수 없습니다. 속성을 무시하도록 `DO_NOTHING`을 지정합니다.

파티션 및 정렬 속성은 `SIGN_ONLY` 또는 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. 속성을 로 정의하는 경우 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

**참고**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 암호화 작업을 사용하려면 AWS Database Encryption SDK 버전 3.3 이상을 사용해야 합니다. 를 포함하도록 [데이터 모델을 업데이트하기 전에 모든 리더](ddb-update-data-model.md)에 새 버전을 배포합니다`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);
```

## AWS Database Encryption SDK for DynamoDB의 암호화 구성
<a name="ddb-config-encrypt"></a>

 AWS Database Encryption SDK를 사용하는 경우 DynamoDB 테이블에 대한 암호화 구성을 명시적으로 정의해야 합니다. 암호화 구성에 필요한 값은 속성 작업을 수동으로 정의했는지 아니면 주석이 달린 데이터 클래스를 사용하여 정의했는지에 따라 달라집니다.

다음 스니펫은 DynamoDB Enhanced Client [https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html)를 사용하는 DynamoDB 테이블 암호화 구성을 정의하고 고유한 접두사로 정의된 서명되지 않은 속성을 허용합니다.

```
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 테이블을 복원](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Restore.Tutorial.html)한 후 DynamoDB 테이블 이름이 변경되더라도 논리적 테이블 이름을 사용하면 복호화 작업에서 테이블을 계속 인식할 수 있습니다.

**허용된 서명되지 않은 속성**  
속성 작업에 `DO_NOTHING`로 표시된 속성.  
허용된 무서명 서명에서 제외되는 속성을 클라이언트에게 알려줍니다. 클라이언트는 다른 모든 속성이 서명에 포함되어 있다고 가정합니다. 그런 다음 레코드를 복호화할 때 클라이언트는 확인해야 할 속성과 지정한 허용된 무서명 속성 중에서 무시할 속성을 결정합니다. 허용된 무서명 속성에서는 속성을 제거할 수 없습니다.  
모든 `DO_NOTHING` 속성을 나열하는 배열을 만들어 무서명 허용 속성을 명시적으로 정의할 수 있습니다. `DO_NOTHING` 속성의 이름을 지정할 때 고유한 접두사를 지정하고 이 접두사를 사용하여 무서명 속성을 클라이언트에게 알릴 수도 있습니다. 고유한 접두사를 지정하는 것이 좋습니다. 이렇게 하면 나중에 새 `DO_NOTHING` 속성을 추가하는 프로세스가 단순해지기 때문입니다. 자세한 내용은 [데이터 모델 업데이트](ddb-update-data-model.md) 단원을 참조하십시오.  
모든 `DO_NOTHING` 속성에 접두사를 지정하지 않는 경우 클라이언트가 복호화 시 서명되지 않을 것으로 예상되는 모든 속성을 명시적으로 나열하는 `allowedUnsignedAttributes` 배열을 구성할 수 있습니다. 반드시 필요한 경우에만 허용된 서명되지 않은 속성을 명시적으로 정의해야 합니다.

**검색 구성(선택 사항)**  
`SearchConfig`는 [비컨 버전](using-beacons.md#beacon-version)을 정의합니다.  
[검색 가능한 암호화](searchable-encryption.md) 또는 [서명된 비컨](configure.md#signed-beacons)을 사용하려면 `SearchConfig`를 지정해야 합니다.

**알고리즘 제품군(선택 사항)**  
`algorithmSuiteId`은 AWS Database Encryption SDK가 사용하는 알고리즘 제품군을 정의합니다.  
대체 알고리즘 제품군을 명시적으로 지정하지 않는 한 AWS Database Encryption SDK는 [기본 알고리즘 제품군](supported-algorithms.md#recommended-algorithms)을 사용합니다. 기본 알고리즘 제품군은 키 도출, [디지털 서명](concepts.md#digital-sigs) 및 [키 커밋](concepts.md#key-commitment)과 함께 AES-GCM 알고리즘을 사용합니다. 기본 알고리즘 제품군이 대부분의 애플리케이션에 적합할 가능성이 높지만 대체 알고리즘 제품군을 선택할 수도 있습니다. 예를 들어, 일부 신뢰 모델은 디지털 서명이 없는 알고리즘 제품군으로 충분할 수 있습니다. AWS Database Encryption SDK가 지원하는 알고리즘 제품군에 대한 자세한 내용은 섹션을 참조하세요[AWS Database Encryption SDK에서 지원되는 알고리즘 제품군](supported-algorithms.md).  
[ECDSA 디지털 서명이 없는 AES-GCM 알고리즘 제품군을](supported-algorithms.md#other-algorithms) 선택하려면 테이블 암호화 구성에 다음 코드 조각을 포함합니다.  

```
.algorithmSuiteId(
    DBEAlgorithmSuiteId.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_SYMSIG_HMAC_SHA384)
```

## AWS Database Encryption SDK로 항목 업데이트
<a name="ddb-update-items"></a>

 AWS Database Encryption SDK는 암호화되거나 서명된 항목에 대해 [ddb:UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)을 지원하지 않습니다. 암호화되거나 서명된 항목을 업데이트하려면 [ddb:PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)을 사용해야 합니다. `PutItem` 요청에 기존 항목과 동일한 프라이머리 키를 지정하면 새 항목이 기존 항목을 완전히 대체합니다. 항목을 업데이트한 후 [CLOBBER](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.SaveBehavior.html#CLOBBER)를 사용하여 저장 시 모든 속성을 지우고 바꿀 수도 있습니다.

## 서명된 집합 암호 해독
<a name="ddb-java-signed-sets"></a>

 AWS Database Encryption SDK 버전 3.0.0 및 3.1.0에서는 [세트 유형](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes.SetTypes) 속성을 로 정의하면 세트의 `SIGN_ONLY`값이 제공된 순서대로 정식화됩니다. DynamoDB는 집합의 순서를 보존하지 않습니다. 따라서 집합을 포함하는 항목의 서명 검증이 실패할 수 있습니다. 집합 속성에 동일한 값이 포함되어 있더라도 집합의 값이 AWS Database Encryption SDK에 제공된 것과 다른 순서로 반환되면 서명 검증이 실패합니다.

**참고**  
 AWS Database Encryption SDK 버전 3.1.1 이상에서는 모든 세트 유형 속성의 값을 정규화하므로 DynamoDB에 기록된 것과 동일한 순서로 값을 읽을 수 있습니다.

서명 검증이 실패하는 경우 암호 해독 작업이 실패하고 다음 오류 메시지가 반환됩니다.


|  | 
| --- |
| software.amazon.cryptography.dbencryptionsdk.structuredencryption.model.StructuredEncryptionException: 일치하는 수신자 태그가 없습니다. | 

위의 오류 메시지가 표시되고 암호 해독하려는 항목에 버전 3.0.0 또는 3.1.0을 사용하여 서명된 세트가 포함되어 있다고 생각되는 경우, GitHub에 있는 aws-database-encryption-sdk-dynamodb-java 리포지토리의 [DecryptWithPermute](https://github.com/aws/aws-database-encryption-sdk-dynamodb-java/tree/v3.1.1/DecryptWithPermute) 디렉터리에서 집합을 성공적으로 검증하는 방법에 대한 자세한 내용을 참조하세요.

# Java 예제
<a name="ddb-java-examples"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

다음 예제에서는 DynamoDB용 Java 클라이언트측 암호화 라이브러리를 사용하여 애플리케이션의 테이블 항목을 보호하는 방법을 보여줍니다. GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에 있는 [Java 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples)에서 더 많은 예제를 찾을 수 있습니다(자체 예제를 제공할 수 있습니다).

다음 예제는 채워지지 않은 새 Amazon DynamoDB 테이블에서 DynamoDB용 Java 클라이언트측 암호화 라이브러리를 구성하는 방법을 보여줍니다. 클라이언트측 암호화를 위해 기존 Amazon DynamoDB 테이블을 구성하려면 [기존 테이블에 버전 3.x 추가](ddb-java-config-existing-table.md) 섹션을 참조하세요.

**Topics**
+ [DynamoDB Enhanced Client 사용](#ddb-java-enhanced-client-example)
+ [하위 수준 DynamoDB API 사용](#ddb-java-lowlevel-API-example)
+ [하위 수준 DynamoDbItemEncryptor 사용](#ddb-java-itemencryptor)

## DynamoDB Enhanced Client 사용
<a name="ddb-java-enhanced-client-example"></a>

다음 예제는 DynamoDB API 호출의 일부로 DynamoDB Enhanced Client와 [AWS KMS 키링](use-kms-keyring.md)을 포함한 `DynamoDbEncryptionInterceptor`을 사용하여 DynamoDB 테이블 항목을 암호화하는 방법을 보여줍니다.

DynamoDB Enhanced Client에서 지원되는 모든 [키링](keyrings.md)을 사용할 수 있지만 가능하면 AWS KMS 키링 중 하나를 사용하는 것이 좋습니다.

**참고**  
DynamoDB Enhanced Client는 [검색 가능한 암호화](searchable-encryption.md)를 지원하지 않습니다. 하위 수준 DynamoDB API와 함께 `DynamoDbEncryptionInterceptor`을 사용하여 검색 가능한 암호화를 사용할 수 있습니다.

**전체 코드 샘플 보기**: [EnhancedPutGetExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/EnhancedPutGetExample.java)

**1단계: AWS KMS 키링 생성**  
다음 예제에서는 `CreateAwsKmsMrkMultiKeyring`를 사용하여 대칭 암호화 KMS AWS KMS 키로 키링을 생성합니다. 이 `CreateAwsKmsMrkMultiKeyring` 방법을 사용하면 키링이 단일 리전 키와 다중 리전 키를 모두 올바르게 처리할 수 있습니다.  

```
final MaterialProviders matProv = MaterialProviders.builder()
        .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
        .build();
final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
        .generator(kmsKeyId)
        .build();
final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**2단계: 주석이 달린 데이터 클래스에서 테이블 스키마 생성**  
다음 예제에서는 주석이 달린 데이터 클래스를 사용하여 `TableSchema`를 만듭니다.  
이 예제에서는 주석이 달린 데이터 클래스와 속성 작업을 [SimpleClass.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/SimpleClass.java)를 사용하여 정의했다고 가정합니다. 속성 작업에 주석을 다는 방법에 대한 자세한 지침은 [주석이 달린 데이터 클래스 사용](ddb-java-using.md#ddb-attribute-actions-annotated-data-class)을 참조하세요.  
 AWS Database Encryption SDK는 [중첩 속성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-adv-features-nested.html)에 대한 주석을 지원하지 않습니다.

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

**3단계: 시그니처에서 제외할 속성을 정의합니다.**  
다음 예제에서는 모든 `DO_NOTHING` 속성이 고유한 접두사 "`:`“를 공유한다고 가정하고 이 접두사를 사용하여 허용된 서명되지 않은 속성을 정의합니다. 클라이언트는 접두사가 "`:`"인 모든 속성 이름이 서명에서 제외된다고 가정합니다. 자세한 내용은 [Allowed unsigned attributes](ddb-java-using.md#allowed-unauth) 단원을 참조하십시오.  

```
final String unsignedAttrPrefix = ":";
```

**4단계: 암호화 구성 생성**  
다음 예제는 DynamoDB 테이블의 암호화 구성을 나타내는 `tableConfigs` 맵을 정의합니다.  
이 예제에서는 DynamoDB 테이블 이름을 [논리적 테이블 이름](ddb-java-using.md#logical-table-name)으로 지정합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB의 암호화 구성](ddb-java-using.md#ddb-config-encrypt) 단원을 참조하십시오.  
[검색 가능한 암호화](searchable-encryption.md) 또는 [서명된 비컨](configure.md#signed-beacons)을 사용하려면 암호화 구성에도 [`SearchConfig`](ddb-java-using.md#ddb-search-config)을 포함해야 합니다.

```
final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
tableConfigs.put(ddbTableName,
    DynamoDbEnhancedTableEncryptionConfig.builder()
        .logicalTableName(ddbTableName)
        .keyring(kmsKeyring)
        .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
        .schemaOnEncrypt(tableSchema)
        .build());
```

**5단계: `DynamoDbEncryptionInterceptor` 생성**  
다음 예제에서는 **4단계**의 `tableConfigs`를 사용하여 새 `DynamoDbEncryptionInterceptor`을 만듭니다.  

```
final DynamoDbEncryptionInterceptor interceptor =
    DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
        CreateDynamoDbEncryptionInterceptorInput.builder()
            .tableEncryptionConfigs(tableConfigs)
            .build()
    );
```

**6단계: 새 AWS SDK DynamoDB 클라이언트 생성**  
다음 예제에서는 **5단계**`interceptor`의를 사용하여 새 AWS SDK DynamoDB 클라이언트를 생성합니다.  

```
final DynamoDbClient ddb = DynamoDbClient.builder()
        .overrideConfiguration(
                ClientOverrideConfiguration.builder()
                       .addExecutionInterceptor(interceptor)
                       .build())
        .build();
```

**7단계: DynamoDB Enhanced Client 생성 및 테이블 생성**  
다음 예제는 **6단**계에서 생성한 AWS SDK DynamoDB client를 사용하여 DynamoDB Enhanced Client를 생성하고 주석이 달린 데이터 클래스를 사용하여 테이블을 생성합니다.  

```
final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
        .dynamoDbClient(ddb)
        .build();
final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
```

**8단계: 테이블 항목 암호화 및 서명**  
다음 예제는 DynamoDB Enhanced Client를 사용하여 DynamoDB 테이블에 항목을 추가합니다. 항목은 DynamoDB로 전송되기 전에 클라이언트측에서 암호화되고 서명됩니다.  

```
final SimpleClass item = new SimpleClass();
item.setPartitionKey("EnhancedPutGetExample");
item.setSortKey(0);
item.setAttribute1("encrypt and sign me!");
item.setAttribute2("sign me!");
item.setAttribute3("ignore me!");

table.putItem(item);
```

## 하위 수준 DynamoDB API 사용
<a name="ddb-java-lowlevel-API-example"></a>

다음 예제는 [AWS KMS 키링](use-kms-keyring.md)이 있는 하위 수준 DynamoDB API를 사용하여 DynamoDB `PutItem` 요청으로 클라이언트측에서 항목을 자동으로 암호화하고 서명하는 방법을 보여줍니다.

지원되는 모든 [키링](keyrings.md)을 사용할 수 있지만 가능하면 AWS KMS 키링 중 하나를 사용하는 것이 좋습니다.

**전체 코드 샘플 보기**: [BasicPutGetExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/BasicPutGetExample.java)

**1단계: AWS KMS 키링 생성**  
다음 예제에서는 `CreateAwsKmsMrkMultiKeyring`를 사용하여 대칭 암호화 KMS AWS KMS 키로 키링을 생성합니다. 이 `CreateAwsKmsMrkMultiKeyring` 방법을 사용하면 키링이 단일 리전 키와 다중 리전 키를 모두 올바르게 처리할 수 있습니다.  

```
final MaterialProviders matProv = MaterialProviders.builder()
         .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
         .build();
final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
        .generator(kmsKeyId)
        .build();
final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**2단계: 속성 작업 구성**  
다음 예제에서는 테이블 항목에 대한 샘플 [속성 작업](concepts.md#crypt-actions)을 나타내는 `attributeActionsOnEncrypt` 맵을 정의합니다.  
다음 예제에서는 속성을 로 정의하지 않습니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

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

**3단계: 시그니처에서 제외할 속성을 정의합니다.**  
다음 예제에서는 모든 `DO_NOTHING` 속성이 고유한 접두사 "`:`“를 공유한다고 가정하고 이 접두사를 사용하여 허용된 서명되지 않은 속성을 정의합니다. 클라이언트는 접두사가 "`:`"인 모든 속성 이름이 서명에서 제외된다고 가정합니다. 자세한 내용은 [Allowed unsigned attributes](ddb-java-using.md#allowed-unauth) 단원을 참조하십시오.  

```
final String unsignedAttrPrefix = ":";
```

**4단계: DynamoDB 테이블 암호화 구성 정의**  
다음 예제는 이 DynamoDB 테이블의 암호화 구성을 나타내는 `tableConfigs` 맵을 정의합니다.  
이 예제에서는 DynamoDB 테이블 이름을 [논리적 테이블 이름](ddb-java-using.md#logical-table-name)으로 지정합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB의 암호화 구성](ddb-java-using.md#ddb-config-encrypt) 단원을 참조하십시오.  
[검색 가능한 암호화](searchable-encryption.md) 또는 [서명된 비컨](configure.md#signed-beacons)을 사용하려면 암호화 구성에도 [`SearchConfig`](ddb-java-using.md#ddb-search-config)을 포함해야 합니다.

```
final Map<String, DynamoDbTableEncryptionConfig> tableConfigs = new HashMap<>();
final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder()
        .logicalTableName(ddbTableName)
        .partitionKeyName("partition_key")
        .sortKeyName("sort_key")
        .attributeActionsOnEncrypt(attributeActionsOnEncrypt)
        .keyring(kmsKeyring)
        .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
        .build();
tableConfigs.put(ddbTableName, config);
```

**5단계: `DynamoDbEncryptionInterceptor` 생성**  
다음 예제는 **4단계**의 `tableConfigs`를 사용하여 `DynamoDbEncryptionInterceptor`을 생성합니다.  

```
DynamoDbEncryptionInterceptor interceptor = DynamoDbEncryptionInterceptor.builder()
        .config(DynamoDbTablesEncryptionConfig.builder()
                .tableEncryptionConfigs(tableConfigs)
                .build())
        .build();
```

**6단계: 새 AWS SDK DynamoDB 클라이언트 생성**  
다음 예제에서는 **5단계**`interceptor`의를 사용하여 새 AWS SDK DynamoDB 클라이언트를 생성합니다.  

```
final DynamoDbClient ddb = DynamoDbClient.builder()
        .overrideConfiguration(
                ClientOverrideConfiguration.builder()
                       .addExecutionInterceptor(interceptor)
                       .build())
        .build();
```

**7단계: DynamoDB 테이블 항목 암호화 및 서명**  
다음 예제는 샘플 테이블 항목을 나타내는 `item` 맵을 정의하고 해당 항목을 DynamoDB 테이블에 배치합니다. 항목은 DynamoDB로 전송되기 전에 클라이언트측에서 암호화되고 서명됩니다.  

```
final HashMap<String, AttributeValue> item = new HashMap<>();
item.put("partition_key", AttributeValue.builder().s("BasicPutGetExample").build());
item.put("sort_key", AttributeValue.builder().n("0").build());
item.put("attribute1", AttributeValue.builder().s("encrypt and sign me!").build());
item.put("attribute2", AttributeValue.builder().s("sign me!").build());
item.put(":attribute3", AttributeValue.builder().s("ignore me!").build());

final PutItemRequest putRequest = PutItemRequest.builder()
        .tableName(ddbTableName)
        .item(item)
        .build();

final PutItemResponse putResponse = ddb.putItem(putRequest);
```

## 하위 수준 DynamoDbItemEncryptor 사용
<a name="ddb-java-itemencryptor"></a>

다음 예제는 [AWS KMS 키링](use-kms-keyring.md)이 있는 하위 수준 `DynamoDbItemEncryptor`을 사용하여 테이블 항목을 직접 암호화하고 서명하는 방법을 보여줍니다. `DynamoDbItemEncryptor`는 DynamoDB 테이블에 항목을 배치하지 않습니다.

DynamoDB Enhanced Client에서 지원되는 모든 [키링](keyrings.md)을 사용할 수 있지만 가능하면 AWS KMS 키링 중 하나를 사용하는 것이 좋습니다.

**참고**  
하위 수준 `DynamoDbItemEncryptor`은 [검색 가능한 암호화](searchable-encryption.md)를 지원하지 않습니다. 하위 수준 DynamoDB API와 함께 `DynamoDbEncryptionInterceptor`을 사용하여 검색 가능한 암호화를 사용할 수 있습니다.

**전체 코드 샘플 보기**: [ItemEncryptDecryptExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/itemencryptor/ItemEncryptDecryptExample.java)

**1단계: AWS KMS 키링 생성**  
다음 예제에서는 `CreateAwsKmsMrkMultiKeyring`를 사용하여 대칭 암호화 KMS AWS KMS 키로 키링을 생성합니다. 이 `CreateAwsKmsMrkMultiKeyring` 방법을 사용하면 키링이 단일 리전 키와 다중 리전 키를 모두 올바르게 처리할 수 있습니다.  

```
final MaterialProviders matProv = MaterialProviders.builder()
         .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
         .build();
final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
        .generator(kmsKeyId)
        .build();
final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**2단계: 속성 작업 구성**  
다음 예제에서는 테이블 항목에 대한 샘플 [속성 작업](concepts.md#crypt-actions)을 나타내는 `attributeActionsOnEncrypt` 맵을 정의합니다.  
다음 예제에서는 속성을 로 정의하지 않습니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

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

**3단계: 시그니처에서 제외할 속성을 정의합니다.**  
다음 예제에서는 모든 `DO_NOTHING` 속성이 고유한 접두사 "`:`“를 공유한다고 가정하고 이 접두사를 사용하여 허용된 서명되지 않은 속성을 정의합니다. 클라이언트는 접두사가 "`:`"인 모든 속성 이름이 서명에서 제외된다고 가정합니다. 자세한 내용은 [Allowed unsigned attributes](ddb-java-using.md#allowed-unauth) 단원을 참조하십시오.  

```
final String unsignedAttrPrefix = ":";
```

**4단계: `DynamoDbItemEncryptor` 구성 정의**  
다음 예제에서는 `DynamoDbItemEncryptor`의 구성을 정의합니다.  
이 예제에서는 DynamoDB 테이블 이름을 [논리적 테이블 이름](ddb-java-using.md#logical-table-name)으로 지정합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB의 암호화 구성](ddb-java-using.md#ddb-config-encrypt) 단원을 참조하십시오.  

```
final DynamoDbItemEncryptorConfig config = DynamoDbItemEncryptorConfig.builder()
        .logicalTableName(ddbTableName)
        .partitionKeyName("partition_key")
        .sortKeyName("sort_key")
        .attributeActionsOnEncrypt(attributeActionsOnEncrypt)
        .keyring(kmsKeyring)
        .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
        .build();
```

**5단계: `DynamoDbItemEncryptor` 생성**  
다음 예제에서는 **4단계**의 `config`를 사용하여 새 `DynamoDbItemEncryptor`을 만듭니다.  

```
final DynamoDbItemEncryptor itemEncryptor = DynamoDbItemEncryptor.builder()
        .DynamoDbItemEncryptorConfig(config)
        .build();
```

**6단계: 테이블 항목을 직접 암호화하고 서명합니다.**  
다음 예제에서는 `DynamoDbItemEncryptor`를 사용하여 항목을 직접 암호화하고 서명합니다. `DynamoDbItemEncryptor`는 DynamoDB 테이블에 항목을 배치하지 않습니다.  

```
final Map<String, AttributeValue> originalItem = new HashMap<>();
originalItem.put("partition_key", AttributeValue.builder().s("ItemEncryptDecryptExample").build());
originalItem.put("sort_key", AttributeValue.builder().n("0").build());
originalItem.put("attribute1", AttributeValue.builder().s("encrypt and sign me!").build());
originalItem.put("attribute2", AttributeValue.builder().s("sign me!").build());
originalItem.put(":attribute3", AttributeValue.builder().s("ignore me!").build());

final Map<String, AttributeValue> encryptedItem = itemEncryptor.EncryptItem(
        EncryptItemInput.builder()
                .plaintextItem(originalItem)
                .build()
).encryptedItem();
```

# DynamoDB용 AWS Database Encryption SDK를 사용하도록 기존 DynamoDB 테이블 구성
<a name="ddb-java-config-existing-table"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

버전 3.*x*를 포함하여 DynamoDB용 Java 클라이언트측 암호화 라이브러리 중 하나를 사용하면 기존 Amazon DynamoDB 테이블을 클라이언트측 암호화를구성할 수 있습니다. 이 주제에서는 채워진 기존 DynamoDB 테이블에 버전 3.*x*를 추가하기 위해 수행해야 하는 세 가지 단계에 대한 지침을 제공합니다.

**사전 조건**  
DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*에는 AWS SDK for Java 2.x 에서 제공하는 [DynamoDB Enhanced Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html)가 필요합니다. [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html)를 계속 사용하는 경우 DynamoDB Enhanced Client를 사용하려면 AWS SDK for Java 2.x 로 마이그레이션해야 합니다.

 [AWS SDK for Java의 버전 1.x에서 2.x로 마이그레이션하기](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html) 지침을 따르세요.

그런 다음 [DynamoDB Enhanced Client API를 사용하여 시작하기](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started.html) 지침을 따르세요.

DynamoDB용 Java 클라이언트측 암호화 라이브러리를 사용하도록 테이블을 구성하기 전에 `TableSchema` [주석이 달린 데이터 클래스를 사용](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html#ddb-en-client-gs-tableschema-anno-bean)을 생성하고 [ 고급 클라이언트를 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)해야 합니다.

## 1단계: 암호화된 항목 읽기 및 쓰기 준비
<a name="ddb-java-add-step1"></a>

다음 단계를 완료하여 AWS Database Encryption SDK 클라이언트가 암호화된 항목을 읽고 쓸 수 있도록 준비합니다. 다음 변경사항을 배포한 후에도 클라이언트는 계속해서 일반 텍스트 항목을 읽고 씁니다. 테이블에 기록된 새 항목을 암호화하거나 서명하지는 않지만 암호화된 항목이 나타나는 즉시 복호화할 수 있습니다. 이러한 변경으로 인해 클라이언트는 [새 항목의 암호화](#ddb-java-add-step2)를 시작할 수 있습니다. 다음 단계로 진행하기 전에 각 리더에 다음 변경 내용을 배포해야 합니다.

**1. [속성 작업](concepts.md#crypt-actions) 정의**  
암호화 및 서명할 속성 값, 서명만 가능한 속성 값, 무시할 속성 값을 정의하는 속성 작업을 포함하도록 주석이 달린 데이터 클래스를 업데이트합니다.  
DynamoDB 향상된 클라이언트 주석에 대한 자세한 지침은 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에서 [SimpleClass.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/SimpleClass.java)를 참조하세요.  
기본적으로 프라이머리 키 속성은 서명되지만 암호화되지는 않으며(`SIGN_ONLY`) 다른 모든 속성은 암호화되고 서명됩니다(`ENCRYPT_AND_SIGN`). 예외를 지정하려면 DynamoDB용 Java 클라이언트측 암호화 라이브러리에 정의된 암호화 주석을 사용합니다. 예를 들어, 특정 속성에 서명되도록 하려면 `@DynamoDbEncryptionSignOnly` 주석만 사용합니다. 특정 속성에 서명하고 암호화 컨텍스트에 포함하려면 `@DynamoDbEncryptionSignAndIncludeInEncryptionContext` 주석을 사용합니다. 특정 속성에 서명되거나 암호화되지 않도록 하려면(`DO_NOTHING`) `@DynamoDbEncryptionDoNothing` 주석을 사용합니다.  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. 를 정의하는 데 사용되는 주석을 보여주는 예제는 [SimpleClass4.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/SimpleClass4.java)를 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`참조하세요.
주석의 예제는 [주석이 달린 데이터 클래스 사용](ddb-java-using.md#ddb-attribute-actions-annotated-data-class) 섹션을 참조하세요.

**2. 서명에서 제외할 속성을 정의합니다.**  
다음 예제에서는 모든 `DO_NOTHING` 속성이 고유한 접두사 "`:`“를 공유한다고 가정하고 이 접두사를 사용하여 허용된 서명되지 않은 속성을 정의합니다. 클라이언트는 접두사가 "`:`"인 모든 속성 이름은 서명에서 제외된 것으로 간주합니다. 자세한 내용은 [Allowed unsigned attributes](ddb-java-using.md#allowed-unauth) 단원을 참조하십시오.  

```
final String unsignedAttrPrefix = ":";
```

**3. [키링](keyrings.md) 생성**  
다음 예제에서는 [AWS KMS 키링](use-kms-keyring.md)을 생성합니다. AWS KMS 키링은 대칭 암호화 또는 비대칭 RSA AWS KMS keys 를 사용하여 데이터 키를 생성, 암호화 및 복호화합니다.  
이 예제에서는 `CreateMrkMultiKeyring`를 사용하여 대칭 암호화 KSM 키를 포함한 AWS KMS 키링을 생성합니다. 이 `CreateAwsKmsMrkMultiKeyring` 방법을 사용하면 키링이 단일 리전 키와 다중 리전 키를 모두 올바르게 처리할 수 있습니다.  

```
final MaterialProviders matProv = MaterialProviders.builder()
        .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
        .build();
final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
        .generator(kmsKeyId)
        .build();
final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**4. DynamoDB 테이블 암호화 구성 정의 **  
다음 예제는 이 DynamoDB 테이블의 암호화 구성을 나타내는 `tableConfigs` 맵을 정의합니다.  
이 예제에서는 DynamoDB 테이블 이름을 [논리적 테이블 이름](ddb-java-using.md#logical-table-name)으로 지정합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB의 암호화 구성](ddb-java-using.md#ddb-config-encrypt) 단원을 참조하십시오.  
`FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT`을 일반 텍스트 오버라이드로 지정해야 합니다. 이 정책은 계속해서 일반 텍스트 항목을 읽고 쓰고, 암호화된 항목을 읽고, 클라이언트가 암호화된 항목을 쓸 수 있도록 준비시킵니다.  

```
final Map<String, DynamoDbTableEncryptionConfig> tableConfigs = new HashMap<>();
final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder()
        .logicalTableName(ddbTableName)
        .partitionKeyName("partition_key")
        .sortKeyName("sort_key")
        .schemaOnEncrypt(tableSchema)
        .keyring(kmsKeyring)
        .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
        .plaintextOverride(PlaintextOverride.FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT)
        .build();
tableConfigs.put(ddbTableName, config);
```

**5. `DynamoDbEncryptionInterceptor` 생성**  
다음 예제는 **3단계**의 `tableConfigs`를 사용하여 `DynamoDbEncryptionInterceptor`을 생성합니다.  

```
DynamoDbEncryptionInterceptor interceptor = DynamoDbEncryptionInterceptor.builder()
        .config(DynamoDbTablesEncryptionConfig.builder()
                .tableEncryptionConfigs(tableConfigs)                
                .build())
        .build();
```

## 2단계: 암호화되고 서명된 항목 쓰기
<a name="ddb-java-add-step2"></a>

`DynamoDbEncryptionInterceptor` 구성의 일반 텍스트 정책을 업데이트하여 클라이언트가 암호화되고 서명된 항목을 쓸 수 있도록 허용합니다. 다음 변경 사항을 배포하면 클라이언트는 **1단계**에서 구성한 속성 작업을 기반으로 새 항목을 암호화하고 서명합니다. 클라이언트는 일반 텍스트 항목과 암호화되고 서명된 항목을 읽을 수 있습니다.

[3단계](#ddb-java-add-step3)로 진행하기 전에 테이블의 기존 일반 텍스트 항목을 모두 암호화하고 서명해야 합니다. 기존 일반 텍스트 항목을 빠르게 암호화하기 위해 실행할 수 있는 단일 지표나 쿼리는 없습니다. 시스템에 가장 적합한 프로세스를 사용하세요. 예를 들어, 테이블을 천천히 스캔한 다음 정의한 속성 작업 및 암호화 구성을 사용하여 항목을 다시 쓰는 비동기 프로세스를 사용할 수 있습니다. 테이블의 일반 텍스트 항목을 식별하려면 암호화되고 서명될 때 AWS Database Encryption SDK가 항목에 추가하는 `aws_dbe_head` 및 `aws_dbe_foot` 속성이 포함되지 않은 모든 항목을 스캔하는 것이 좋습니다.

다음 예시에서는 **1단계**의 테이블 암호화 구성을 업데이트합니다. 일반 텍스트 오버라이드를 `FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT`로 업데이트해야 합니다. 이 정책은 일반 텍스트 항목을 계속 읽지만 암호화된 항목을 읽고 쓸 수도 있습니다. 업데이트된를 `DynamoDbEncryptionInterceptor` 사용하여 새를 생성합니다`tableConfigs`.

```
final Map<String, DynamoDbTableEncryptionConfig> tableConfigs = new HashMap<>();
final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder()
        .logicalTableName(ddbTableName)
        .partitionKeyName("partition_key")
        .sortKeyName("sort_key")
        .schemaOnEncrypt(tableSchema)
        .keyring(kmsKeyring)
        .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
        .plaintextOverride(PlaintextOverride.FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT)
        .build();
tableConfigs.put(ddbTableName, config);
```

## 3단계: 암호화되고 서명된 항목만 읽기
<a name="ddb-java-add-step3"></a>

모든 항목을 암호화하고 서명한 후에는 `DynamoDbEncryptionInterceptor` 구성의 일반 텍스트 재정의를 업데이트하여 클라이언트가 암호화되고 서명된 항목만 읽고 쓸 수 있도록 합니다. 다음 변경 사항을 배포하면 클라이언트는 **1단계**에서 구성한 속성 작업을 기반으로 새 항목을 암호화하고 서명합니다. 클라이언트는 암호화되고 서명된 항목만 읽을 수 있습니다.

다음 예시에서는 **2단계**의 테이블 암호화 구성을 업데이트합니다. `FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT`으로 일반 텍스트 재정의를 업데이트하거나 구성에서 일반 텍스트 정책을 제거할 수 있습니다. 클라이언트는 기본적으로 암호화되고 서명된 항목만 읽고 씁니다. 업데이트된를 `DynamoDbEncryptionInterceptor` 사용하여 새를 생성합니다`tableConfigs`.

```
final Map<String, DynamoDbTableEncryptionConfig> tableConfigs = new HashMap<>();
final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder()
        .logicalTableName(ddbTableName)
        .partitionKeyName("partition_key")
        .sortKeyName("sort_key")
        .schemaOnEncrypt(tableSchema)
        .keyring(kmsKeyring)
        .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
        // Optional: you can also remove the plaintext policy from your configuration
        .plaintextOverride(PlaintextOverride.FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT)
        .build();
tableConfigs.put(ddbTableName, config);
```

# DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.x로 마이그레이션
<a name="ddb-java-migrate"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*는 2.*x* 코드 베이스를 대대적으로 재작성한 것입니다. 여기에는 새로운 구조화된 데이터 형식, 향상된 멀티테넌시 지원, 원활한 스키마 변경, 검색 가능한 암호화 지원 등 많은 업데이트가 포함되어 있습니다. 이 항목에서는 코드를 버전 3.*x*으로 마이그레이션하는 방법에 대한 지침을 제공합니다.

## 버전 1.x에서 2.x로 마이그레이션
<a name="ddb-java-v1-to-v2"></a>

버전 3.*x*로 마이그레이션하기 전에 버전 2.*x*로 마이그레이션합니다. 버전 2.*x*에서는 Most Recent Provider의 기호가 `MostRecentProvider`에서 `CachingMostRecentProvider`로 변경되었습니다. 현재 `MostRecentProvider` 기호와 함께 DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 1.*x* 를 사용하는 경우 코드의 기호 이름을 `CachingMostRecentProvider`으로 업데이트해야 합니다. 자세한 내용은 [Most Recent Provider 업데이트](most-recent-provider.md#mrp-versions)를 참조하세요.

## 버전 2.x에서 3.x로 마이그레이션
<a name="ddb-java-v2-to-v3"></a>

다음 절차에서는 코드를 DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 2.*x*에서 버전 3.*x*로 마이그레이션하는 방법을 설명합니다.

### 1단계. 새 형식의 항목을 읽을 준비하기
<a name="ddb-java-migrate-step1"></a>

다음 단계를 완료하여 AWS Database Encryption SDK 클라이언트가 새 형식으로 항목을 읽을 수 있도록 준비합니다. 다음 변경 사항을 배포한 후에도 클라이언트는 버전 2.*x*에서와 동일한 방식으로 계속 동작합니다. 클라이언트는 계속해서 버전 2.*x* 형식의 항목을 읽고 쓰지만 이러한 변경 사항을 통해 클라이언트는 [새 형식의 항목을 읽을 수 있도록](#ddb-java-migrate-step2) 준비합니다.

**를 버전 2.x AWS SDK for Java 로 업데이트**  
DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*에는 [DynamoDB Enhanced Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html)가 필요합니다. DynamoDB Enhanced Client는 이전 버전에서 사용된 [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html)를 대체합니다. 향상된 클라이언트를 사용하려면 AWS SDK for Java 2.x를 사용해야 합니다.  
[AWS SDK for Java의 버전 1.x에서 2.x로 마이그레이션하기](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html) 지침을 따르세요.  
필요한 AWS SDK for Java 2.x 모듈에 대한 자세한 내용은 섹션을 참조하세요[사전 조건](ddb-java.md#ddb-java-prerequisites).

**레거시 버전으로 암호화된 항목을 읽도록 클라이언트 구성**  
다음 절차는 아래 코드 예제에 나와 있는 단계의 개요를 제공합니다.  

1. [키링](keyrings.md)을 생성합니다.

   키링 및 [암호화 자료 관리자](concepts.md#crypt-materials-manager)는 이전 버전의 DynamoDB용 Java 클라이언트측 암호화 라이브러리에서 사용하던 암호화 자료 공급자를 대체합니다.
**중요**  
키링을 생성할 때 지정하는 래핑 키는 버전 2.*x*에서 암호화 자료 공급자에 사용한 래핑 키와 동일해야 합니다.

1. 주석이 달린 클래스 위에 테이블 스키마를 만듭니다.

   이 단계에서는 새 형식으로 항목을 작성하기 시작할 때 사용할 속성 작업을 정의합니다.

   새로운 DynamoDB Enhanced Client 사용에 대한 지침은 *AWS SDK for Java 개발자 안내서*의 [`TableSchema` 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html)을 참조하세요.

   다음 예제에서는 새 속성 작업 주석을 사용하여 버전 2.*x*에서 주석이 달린 클래스를 업데이트했다고 가정합니다. 속성 작업에 주석을 다는 방법에 대한 자세한 지침은 [주석이 달린 데이터 클래스 사용](ddb-java-using.md#ddb-attribute-actions-annotated-data-class)을 참조하세요.
**참고**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. 를 정의하는 데 사용되는 주석을 보여주는 예제는 [SimpleClass4.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/SimpleClass4.java)를 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`참조하세요.

1. [서명에서 제외할 속성](ddb-java-using.md#allowed-unauth)을 정의합니다.

1. 버전 2.x 모델 클래스에 구성된 속성 작업의 명시적 맵을 구성합니다.

   이 단계에서는 이전 형식으로 항목을 작성하는 데 사용되는 속성 작업을 정의합니다.

1. DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 2.*x*에서 사용한 `DynamoDBEncryptor`을 구성합니다.

1. 레거시 동작을 구성합니다.

1. `DynamoDbEncryptionInterceptor`를 만듭니다.

1. 새 AWS SDK DynamoDB 클라이언트를 생성합니다.

1. `DynamoDBEnhancedClient`를 만들고 모델링된 클래스로 테이블을 생성합니다.

   DynamoDB Enhanced Client에 대한 자세한 내용은 [향상된 클라이언트 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)을 참조하세요.

```
public class MigrationExampleStep1 {

    public static void MigrationStep1(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Create a Keyring.
        //    This example creates an AWS KMS Keyring that specifies the 
        //    same kmsKeyId previously used in the version 2.x configuration.
        //    It uses the 'CreateMrkMultiKeyring' method to create the 
        //    keyring, so that the keyring can correctly handle both single
        //    region and Multi-Region KMS Keys.
        //    Note that this example uses the AWS SDK for Java v2 KMS client.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
                .generator(kmsKeyId)
                .build();
        final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);

        // 2. Create a Table Schema over your annotated class.
        //    For guidance on using the new attribute actions 
        //    annotations, see SimpleClass.java in the 
        //    aws-database-encryption-sdk-dynamodb GitHub repository. 
        //    All primary key attributes must be signed but not encrypted 
        //    and by default all non-primary key attributes 
        //    are encrypted and signed (ENCRYPT_AND_SIGN).
        //    If you want a particular non-primary key attribute to be signed but
        //    not encrypted, use the 'DynamoDbEncryptionSignOnly' annotation.
        //    If you want a particular attribute to be neither signed nor encrypted
        //    (DO_NOTHING), use the 'DynamoDbEncryptionDoNothing' annotation.
        final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class);

        // 3. Define which attributes the client should expect to be excluded 
        //    from the signature when reading items.
        //    This value represents all unsigned attributes across the entire 
        //    dataset.
        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");

        // 4. Configure an explicit map of the attribute actions configured 
        //    in your version 2.x modeled class.
        final Map<String, CryptoAction> legacyActions = new HashMap<>();
        legacyActions.put("partition_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("sort_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN);
        legacyActions.put("attribute2", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute3", CryptoAction.DO_NOTHING);

        // 5. Configure the DynamoDBEncryptor that you used in version 2.x.
        final AWSKMS kmsClient = AWSKMSClientBuilder.defaultClient();
        final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kmsClient, kmsKeyId);
        final DynamoDBEncryptor oldEncryptor = DynamoDBEncryptor.getInstance(cmp);

        // 6. Configure the legacy behavior.
        //    Input the DynamoDBEncryptor and attribute actions created in 
        //    the previous steps. For Legacy Policy, use 
        //    'FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT'. This policy continues to read 
        //    and write items using the old format, but will be able to read
        //    items written in the new format as soon as they appear.
        final LegacyOverride legacyOverride = LegacyOverride
                .builder()
                .encryptor(oldEncryptor)
                .policy(LegacyPolicy.FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT)
                .attributeActionsOnEncrypt(legacyActions)
                .build();

        // 7. Create a DynamoDbEncryptionInterceptor with the above configuration.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .legacyOverride(legacyOverride)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 8. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 7.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 9. Create the DynamoDbEnhancedClient using the AWS SDK DynamoDb client 
        //    created in Step 8, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```

### 2단계. 새 형식으로 항목 작성
<a name="ddb-java-migrate-step2"></a>

1단계의 변경 사항을 모든 리더에 배포한 후 다음 단계를 완료하여 새 형식으로 항목을 작성하도록 AWS Database Encryption SDK 클라이언트를 구성합니다. 다음 변경 사항을 배포한 후 클라이언트는 이전 형식의 항목을 계속 읽고 새 형식의 항목을 쓰고 읽기 시작합니다.

다음 절차는 아래 코드 예제에 나와 있는 단계의 개요를 제공합니다.

1. [**1단계**](#ddb-java-migrate-step1)에서 했던 것처럼 키링, 테이블 스키마, 레거시 속성 작업, `allowedUnsignedAttributes` 및 `DynamoDBEncryptor`를 계속 구성합니다.

1. 새 형식을 사용하여 새 항목만 작성하도록 레거시 동작을 업데이트합니다.

1. `DynamoDbEncryptionInterceptor ` 생성

1. 새 AWS SDK DynamoDB 클라이언트를 생성합니다.

1. `DynamoDBEnhancedClient`를 만들고 모델링된 클래스로 테이블을 생성합니다.

   DynamoDB Enhanced Client에 대한 자세한 내용은 [향상된 클라이언트 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)을 참조하세요.

```
public class MigrationExampleStep2 {

    public static void MigrationStep2(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Continue to configure your keyring, table schema, legacy 
        //    attribute actions, allowedUnsignedAttributes, and 
        //    DynamoDBEncryptor as you did in Step 1.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
                .generator(kmsKeyId)
                .build();
        final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);

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

        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");

        final Map<String, CryptoAction> legacyActions = new HashMap<>();
        legacyActions.put("partition_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("sort_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN);
        legacyActions.put("attribute2", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute3", CryptoAction.DO_NOTHING);

        final AWSKMS kmsClient = AWSKMSClientBuilder.defaultClient();
        final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kmsClient, kmsKeyId);
        final DynamoDBEncryptor oldEncryptor = DynamoDBEncryptor.getInstance(cmp);

        // 2. Update your legacy behavior to only write new items using the new
        //    format. 
        //    For Legacy Policy, use 'FORBID_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT'. This policy
        //    continues to read items in both formats, but will only write items
        //    using the new format.
        final LegacyOverride legacyOverride = LegacyOverride
                .builder()
                .encryptor(oldEncryptor)
                .policy(LegacyPolicy.FORBID_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT)
                .attributeActionsOnEncrypt(legacyActions)
                .build();

        // 3. Create a DynamoDbEncryptionInterceptor with the above configuration.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .legacyOverride(legacyOverride)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 4. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 3.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 5. Create the DynamoDbEnhancedClient using the AWS SDK DynamoDb Client created
        //    in Step 4, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```

2단계 변경 사항을 배포한 후에는 테이블의 모든 이전 항목을 새 형식으로 다시 암호화해야 [3단계](#ddb-java-migrate-step3)로 넘어갈 수 있습니다. 기존 항목을 빠르게 암호화하기 위해 실행할 수 있는 단일 지표나 쿼리는 없습니다. 시스템에 가장 적합한 프로세스를 사용하세요. 예를 들어, 테이블을 천천히 스캔한 다음 정의한 새 속성 작업 및 암호화 구성을 사용하여 항목을 다시 쓰는 비동기 프로세스를 사용할 수 있습니다.

### 3단계. 새 형식의 항목만 읽고 쓸 수 있습니다
<a name="ddb-java-migrate-step3"></a>

테이블의 모든 항목을 새 형식으로 다시 암호화한 후 구성에서 기존 동작을 제거할 수 있습니다. 클라이언트가 새 형식의 항목만 읽고 쓰도록 구성하려면 다음 단계를 수행합니다.

다음 절차는 아래 코드 예제에 나와 있는 단계의 개요를 제공합니다.

1. [**1단계에서**](#ddb-java-migrate-step1) 수행한 것처럼 키링, 테이블 스키마, `allowedUnsignedAttributes`을 계속 구성합니다. 구성에서 레거시 속성 작업 및 `DynamoDBEncryptor`을 제거합니다.

1. `DynamoDbEncryptionInterceptor`를 만듭니다.

1. 새 AWS SDK DynamoDB 클라이언트를 생성합니다.

1. `DynamoDBEnhancedClient`를 만들고 모델링된 클래스로 테이블을 생성합니다.

   DynamoDB Enhanced Client에 대한 자세한 내용은 [향상된 클라이언트 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)을 참조하세요.

```
public class MigrationExampleStep3 {

    public static void MigrationStep3(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Continue to configure your keyring, table schema,
        //    and allowedUnsignedAttributes as you did in Step 1.
        //    Do not include the configurations for the DynamoDBEncryptor or 
        //    the legacy attribute actions.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
                .generator(kmsKeyId)
                .build();
        final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);

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

        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");


        // 3. Create a DynamoDbEncryptionInterceptor with the above configuration.
        //    Do not configure any legacy behavior.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 4. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 3.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 5. Create the DynamoDbEnhancedClient using the AWS SDK Client 
        //    created in Step 4, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```

# .NET
<a name="ddb-net"></a>

이 주제에서는 DynamoDB용 .NET 클라이언트 측 암호화 라이브러리 버전 3.*x*를 설치하고 사용하는 방법을 설명합니다. DynamoDB용 AWS Database Encryption SDK를 사용한 프로그래밍에 대한 자세한 내용은 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에 있는 [.NET 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/)를 참조하세요.

DynamoDB용 .NET 클라이언트 측 암호화 라이브러리는 C\$1 및 기타 .NET 프로그래밍 언어로 애플리케이션을 작성하는 개발자를 위한 것입니다. 이는 Windows, macOS, Linux에서 지원됩니다.

 AWS Database Encryption SDK for DynamoDB의 모든 [프로그래밍 언어](ddb-programming-languages.md) 구현은 상호 운용 가능합니다. 그러나 SDK for .NET 는 목록 또는 맵 데이터 유형에 빈 값을 지원하지 않습니다. 즉, DynamoDB용 Java 클라이언트 측 암호화 라이브러리를 사용하여 목록 또는 맵 데이터 유형에 대한 빈 값이 포함된 항목을 작성하는 경우 DynamoDB용 .NET 클라이언트 측 암호화 라이브러리를 사용하여 해당 항목을 해독하고 읽을 수 없습니다.

**Topics**
+ [설치](#ddb-net-install)
+ [디버깅](#ddb-net-debugging)
+ [.NET 클라이언트 사용](ddb-net-using.md)
+ [.NET 예제](ddb-net-examples.md)
+ [기존 테이블에 버전 3.x 추가](ddb-net-config-existing-table.md)

## DynamoDB용 .NET 클라이언트 측 암호화 라이브러리 설치
<a name="ddb-net-install"></a>

DynamoDB용 .NET 클라이언트 측 암호화 라이브러리는 NuGet의 [AWS.Cryptography.DbEncryptionSDK.DynamoDb](https://www.nuget.org/packages/AWS.Cryptography.DbEncryptionSDK.DynamoDb/) 패키지로 사용할 수 있습니다. 라이브러리 설치 및 빌드에 대한 자세한 내용은 aws-database-encryption-sdk-dynamodb 리포지토리의 [.NET README.md](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/DynamoDbEncryption/runtimes/net/README.md) 파일을 참조하세요. DynamoDB용 .NET 클라이언트 측 암호화 라이브러리에는 AWS Key Management Service (AWS KMS) 키를 사용하지 SDK for .NET 않더라도가 필요합니다. 는 SDK for .NET NuGet 패키지와 함께 설치됩니다.

DynamoDB용 .NET 클라이언트 측 암호화 라이브러리 버전 3.*x*는 .NET 6.0 및 .NET Framework net48 이상을 지원합니다.

## .NET을 사용한 디버깅
<a name="ddb-net-debugging"></a>

DynamoDB용 .NET 클라이언트 측 암호화 라이브러리는 로그를 생성하지 않습니다. DynamoDB용 .NET 클라이언트 측 암호화 라이브러리의 예외는 예외 메시지를 생성하지만 스택 트레이스는 생성하지 않습니다.

디버깅에 도움이 되도록 SDK for .NET에서 로그인을 활성화해야 합니다. 의 로그 및 오류 메시지는에서 발생하는 오류를 DynamoDB용 .NET 클라이언트 측 암호화 라이브러리의 오류 SDK for .NET 와 구별하는 데 도움이 될 SDK for .NET 수 있습니다. SDK for .NET 로깅에 대한 도움말은 *AWS SDK for .NET 개발자 안내서*의 [AWSLogging](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-config-other.html#config-setting-awslogging)을 참조하세요. (이 주제를 보려면 **.NET Framework 콘텐츠를 열어서 보기** 섹션을 확장하세요.)

# DynamoDB용 .NET 클라이언트 측 암호화 라이브러리 사용
<a name="ddb-net-using"></a>

이 주제에서는 DynamoDB용 .NET 클라이언트 측 암호화 라이브러리 버전 3.*x*의 일부 함수 및 헬퍼 클래스에 대해 설명합니다.

DynamoDB용 .NET 클라이언트 측 암호화 라이브러리를 사용한 프로그래밍에 대한 자세한 내용은 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에서 [.NET 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/)를 참조하세요.

**Topics**
+ [항목 암호화 도구](#ddb-net-item-encryptors)
+ [속성 작업](#ddb-net-attribute-actions)
+ [암호화 구성](#ddb-net-config-encrypt)
+ [항목 업데이트](#ddb-net-update-items)

## 항목 암호화 도구
<a name="ddb-net-item-encryptors"></a>

코어에서 AWS Database Encryption SDK for DynamoDB는 항목 암호화 도구입니다. DynamoDB용 .NET 클라이언트 측 암호화 라이브러리 버전 3.*x*를 사용하여 다음과 같은 방법으로 DynamoDB 테이블 항목을 암호화, 서명, 확인 및 해독할 수 있습니다.

**DynamoDB API용 하위 수준 AWS Database Encryption SDK**  
[테이블 암호화 구성을](#ddb-net-config-encrypt) 사용하여 DynamoDB `PutItem` 요청으로 클라이언트 측 항목을 자동으로 암호화하고 서명하는 DynamoDB 클라이언트를 구성할 수 있습니다. 이 클라이언트를 직접 사용하거나 [문서 모델](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-document) 또는 [객체 지속성 모델을](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-object-persistence) 구성할 수 있습니다.  
[검색 가능한](searchable-encryption.md) 암호화를 사용하려면 하위 수준 AWS Database Encryption SDK for DynamoDB API를 사용해야 합니다.

**하위 수준 `DynamoDbItemEncryptor`**  
하위 수준 `DynamoDbItemEncryptor`에서는 DynamoDB를 호출하지 않고도 테이블 항목을 직접 암호화하고 서명 또는 복호화하고 확인합니다. DynamoDB `PutItem` 또는 `GetItem` 요청을 하지 않습니다. 예를 들어 하위 수준 `DynamoDbItemEncryptor`을 사용하여 이미 검색한 DynamoDB 항목을 직접 복호화하고 확인할 수 있습니다. 하위 수준를 사용하는 경우 DynamoDB와 통신하기 위해에서 SDK for .NET 제공하는 [하위 수준 프로그래밍 모델을](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-low-level) 사용하는 `DynamoDbItemEncryptor`것이 좋습니다.  
하위 수준 `DynamoDbItemEncryptor`은 [검색 가능한 암호화](searchable-encryption.md)를 지원하지 않습니다.

## AWS Database Encryption SDK for DynamoDB의 속성 작업
<a name="ddb-net-attribute-actions"></a>

[속성 작업은](concepts.md#crypt-actions) 암호화 및 서명되는 속성 값, 서명만 되는 속성 값, 암호화 컨텍스트에 서명 및 포함되는 속성 값, 무시되는 속성 값을 결정합니다.

.NET 클라이언트로 속성 작업을 지정하려면 객체 모델을 사용하여 속성 작업을 수동으로 정의합니다. 이름-값 페어가 속성 이름과 지정된 작업을 나타내는 `Dictionary` 객체를 생성하여 속성 작업을 지정합니다.

속성을 암호화하고 서명하도록 `ENCRYPT_AND_SIGN`을 지정합니다. 속성을 서명하되 암호화하지 않도록 `SIGN_ONLY`을 지정합니다. 를 지정`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`하여 속성에 서명하고 암호화 컨텍스트에 포함합니다. 서명하지 않으면 속성을 암호화할 수 없습니다. 속성을 무시하도록 `DO_NOTHING`을 지정합니다.

파티션 및 정렬 속성은 `SIGN_ONLY` 또는 중 하나여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. 속성을 로 정의하면 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

**참고**  
속성 작업을 정의한 후에는 서명에서 제외할 속성을 정의해야 합니다. 나중에 서명되지 않은 새 속성을 더 쉽게 추가할 수 있도록 서명되지 않은 속성을 식별할 고유한 접두사(예: "`:`“)를 선택하는 것이 좋습니다. DynamoDB 스키마와 속성 작업을 정의할 때 `DO_NOTHING`로 표시된 모든 속성의 속성 이름에 이 접두사를 포함합니다.

다음 객체 모델은 .NET 클라이언트를 사용하여 `ENCRYPT_AND_SIGN`, `SIGN_ONLY``SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`, 및 `DO_NOTHING` 속성 작업을 지정하는 방법을 보여줍니다. 이 예제에서는 접두사 "`:`"를 사용하여 `DO_NOTHING` 속성을 식별합니다.

**참고**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 암호화 작업을 사용하려면 AWS Database Encryption SDK 버전 3.3 이상을 사용해야 합니다. 를 포함하도록 [데이터 모델을 업데이트하기 전에 모든 리더](ddb-update-data-model.md)에 새 버전을 배포합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

```
var attributeActionsOnEncrypt = new Dictionary<string, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT, // The partition attribute must be signed
    ["sort_key"] = CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT, // The sort attribute must be signed
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    ["attribute3"] = CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
    [":attribute4"] = CryptoAction.DO_NOTHING
};
```

## AWS Database Encryption SDK for DynamoDB의 암호화 구성
<a name="ddb-net-config-encrypt"></a>

 AWS Database Encryption SDK를 사용하는 경우 DynamoDB 테이블에 대한 암호화 구성을 명시적으로 정의해야 합니다. 암호화 구성에 필요한 값은 속성 작업을 수동으로 정의했는지 아니면 주석이 달린 데이터 클래스를 사용하여 정의했는지에 따라 달라집니다.

다음 코드 조각은 하위 수준 AWS Database Encryption SDK for DynamoDB API를 사용하여 DynamoDB 테이블 암호화 구성을 정의하고 고유한 접두사로 정의된 서명되지 않은 속성을 허용합니다.

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    // Optional: SearchConfig only required if you use beacons
    Search = new SearchConfig
    {
        WriteVersion = 1, // MUST be 1
        Versions = beaconVersions
    }    
};
tableConfigs.Add(ddbTableName, config);
```

**논리적 테이블 이름**  
DynamoDB 테이블의 논리적 테이블 이름.  
논리적 테이블 이름은 테이블에 저장된 모든 데이터에 암호로 바인딩되어 DynamoDB 복원 작업을 간소화합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다. 항상 같은 논리적 테이블 이름을 지정해야 합니다. 복호화이 성공하려면 논리적 테이블 이름이 암호화에 지정된 이름과 일치해야 합니다. [백업에서 DynamoDB 테이블을 복원](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Restore.Tutorial.html)한 후 DynamoDB 테이블 이름이 변경되더라도 논리적 테이블 이름을 사용하면 복호화 작업에서 테이블을 계속 인식할 수 있습니다.

**허용된 서명되지 않은 속성**  
속성 작업에 `DO_NOTHING`로 표시된 속성.  
허용된 무서명 서명에서 제외되는 속성을 클라이언트에게 알려줍니다. 클라이언트는 다른 모든 속성이 서명에 포함되어 있다고 가정합니다. 그런 다음 레코드를 복호화할 때 클라이언트는 확인해야 할 속성과 지정한 허용된 무서명 속성 중에서 무시할 속성을 결정합니다. 허용된 무서명 속성에서는 속성을 제거할 수 없습니다.  
모든 `DO_NOTHING` 속성을 나열하는 배열을 만들어 무서명 허용 속성을 명시적으로 정의할 수 있습니다. `DO_NOTHING` 속성의 이름을 지정할 때 고유한 접두사를 지정하고 이 접두사를 사용하여 무서명 속성을 클라이언트에게 알릴 수도 있습니다. 고유한 접두사를 지정하는 것이 좋습니다. 이렇게 하면 나중에 새 `DO_NOTHING` 속성을 추가하는 프로세스가 단순해지기 때문입니다. 자세한 내용은 [데이터 모델 업데이트](ddb-update-data-model.md) 단원을 참조하십시오.  
모든 `DO_NOTHING` 속성에 접두사를 지정하지 않는 경우 클라이언트가 복호화 시 서명되지 않을 것으로 예상되는 모든 속성을 명시적으로 나열하는 `allowedUnsignedAttributes` 배열을 구성할 수 있습니다. 반드시 필요한 경우에만 허용된 서명되지 않은 속성을 명시적으로 정의해야 합니다.

**검색 구성(선택 사항)**  
`SearchConfig`는 [비컨 버전](using-beacons.md#beacon-version)을 정의합니다.  
[검색 가능한 암호화](searchable-encryption.md) 또는 [서명된 비컨](configure.md#signed-beacons)을 사용하려면 `SearchConfig`를 지정해야 합니다.

**알고리즘 제품군(선택 사항)**  
`algorithmSuiteId`은 AWS Database Encryption SDK가 사용하는 알고리즘 제품군을 정의합니다.  
대체 알고리즘 제품군을 명시적으로 지정하지 않는 한 AWS Database Encryption SDK는 [기본 알고리즘 제품군](supported-algorithms.md#recommended-algorithms)을 사용합니다. 기본 알고리즘 제품군은 키 도출, [디지털 서명](concepts.md#digital-sigs) 및 [키 커밋](concepts.md#key-commitment)과 함께 AES-GCM 알고리즘을 사용합니다. 기본 알고리즘 제품군이 대부분의 애플리케이션에 적합할 가능성이 높지만 대체 알고리즘 제품군을 선택할 수도 있습니다. 예를 들어, 일부 신뢰 모델은 디지털 서명이 없는 알고리즘 제품군으로 충분할 수 있습니다. AWS Database Encryption SDK가 지원하는 알고리즘 제품군에 대한 자세한 내용은 섹션을 참조하세요[AWS Database Encryption SDK에서 지원되는 알고리즘 제품군](supported-algorithms.md).  
[ECDSA 디지털 서명이 없는 AES-GCM 알고리즘 제품군을](supported-algorithms.md#other-algorithms) 선택하려면 테이블 암호화 구성에 다음 코드 조각을 포함합니다.  

```
AlgorithmSuiteId = DBEAlgorithmSuiteId.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_SYMSIG_HMAC_SHA384
```

## AWS Database Encryption SDK로 항목 업데이트
<a name="ddb-net-update-items"></a>

 AWS Database Encryption SDK는 암호화되거나 서명된 속성이 포함된 항목에 대해 [ddb:UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)을 지원하지 않습니다. 암호화되거나 서명된 속성을 업데이트하려면 [ddb:PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)을 사용해야 합니다. `PutItem` 요청에 기존 항목과 동일한 프라이머리 키를 지정하면 새 항목이 기존 항목을 완전히 대체합니다. 항목을 업데이트한 후 [CLOBBER](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.SaveBehavior.html#CLOBBER)를 사용하여 저장 시 모든 속성을 지우고 바꿀 수도 있습니다.

# .NET 예제
<a name="ddb-net-examples"></a>

다음 예제에서는 DynamoDB용 .NET 클라이언트 측 암호화 라이브러리를 사용하여 애플리케이션의 테이블 항목을 보호하는 방법을 보여줍니다. 더 많은 예제를 찾으려면(자신에게 기여하려면) GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에서 [.NET 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/net/src)를 참조하세요.

다음 예제에서는 채워지지 않은 새 Amazon DynamoDB 테이블에서 DynamoDB에 대한 .NET 클라이언트 측 암호화 라이브러리를 구성하는 방법을 보여줍니다. 클라이언트측 암호화를 위해 기존 Amazon DynamoDB 테이블을 구성하려면 [기존 테이블에 버전 3.x 추가](ddb-net-config-existing-table.md) 섹션을 참조하세요.

**Topics**
+ [DynamoDB API용 하위 수준 AWS 데이터베이스 암호화 SDK 사용](#ddb-net-lowlevel-API-example)
+ [하위 수준 사용 `DynamoDbItemEncryptor`](#ddb-net-itemencryptor)

## DynamoDB API용 하위 수준 AWS 데이터베이스 암호화 SDK 사용
<a name="ddb-net-lowlevel-API-example"></a>

다음 예제에서는 하위 수준 AWS Database Encryption SDK for DynamoDB API를 [AWS KMS 키링](use-kms-keyring.md)과 함께 사용하여 DynamoDB `PutItem` 요청으로 클라이언트 측 항목을 자동으로 암호화하고 서명하는 방법을 보여줍니다.

지원되는 모든 [키링](keyrings.md)을 사용할 수 있지만 가능하면 AWS KMS 키링 중 하나를 사용하는 것이 좋습니다.

**전체 코드 샘플**: [BasicPutGetExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/BasicPutGetExample.cs) 참조

**1단계: AWS KMS 키링 생성**  
다음 예제에서는 `CreateAwsKmsMrkMultiKeyring`를 사용하여 대칭 암호화 KMS AWS KMS 키로 키링을 생성합니다. 이 `CreateAwsKmsMrkMultiKeyring` 방법을 사용하면 키링이 단일 리전 키와 다중 리전 키를 모두 올바르게 처리할 수 있습니다.  

```
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId };
var kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**2단계: 속성 작업 구성**  
다음 예제에서는 테이블 항목에 대한 샘플 [속성 작업을](concepts.md#crypt-actions) 나타내는 `attributeActionsOnEncrypt` 사전을 정의합니다.  
다음 예제에서는 속성을 로 정의하지 않습니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

```
var attributeActionsOnEncrypt = new Dictionary<string, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_ONLY, // The partition attribute must be SIGN_ONLY
    ["sort_key"] = CryptoAction.SIGN_ONLY, // The sort attribute must be SIGN_ONLY
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    [":attribute3"] = CryptoAction.DO_NOTHING
};
```

**3단계: 시그니처에서 제외할 속성을 정의합니다.**  
다음 예제에서는 모든 `DO_NOTHING` 속성이 고유한 접두사 "`:`“를 공유한다고 가정하고 이 접두사를 사용하여 허용된 서명되지 않은 속성을 정의합니다. 클라이언트는 접두사가 "`:`"인 모든 속성 이름이 서명에서 제외된다고 가정합니다. 자세한 내용은 [Allowed unsigned attributes](ddb-net-using.md#net-allowed-unauth) 단원을 참조하십시오.  

```
const String unsignAttrPrefix = ":";
```

**4단계: DynamoDB 테이블 암호화 구성 정의**  
다음 예제는 이 DynamoDB 테이블의 암호화 구성을 나타내는 `tableConfigs` 맵을 정의합니다.  
이 예제에서는 DynamoDB 테이블 이름을 [논리적 테이블 이름](ddb-net-using.md#net-logical-table-name)으로 지정합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB의 암호화 구성](ddb-net-using.md#ddb-net-config-encrypt) 단원을 참조하십시오.  
[검색 가능한 암호화](searchable-encryption.md) 또는 [서명된 비컨](configure.md#signed-beacons)을 사용하려면 암호화 구성에도 [`SearchConfig`](ddb-java-using.md#ddb-search-config)을 포함해야 합니다.

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix
};
tableConfigs.Add(ddbTableName, config);
```

**5단계: 새 AWS SDK DynamoDB 클라이언트 생성**  
다음 예제에서는 **4단계**`TableEncryptionConfigs`의를 사용하여 새 AWS SDK DynamoDB 클라이언트를 생성합니다.  

```
var ddb = new Client.DynamoDbClient(
    new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs });
```

**6단계: DynamoDB 테이블 항목 암호화 및 서명**  
다음 예제에서는 샘플 테이블 항목을 나타내는 `item` 사전을 정의하고 DynamoDB 테이블에 해당 항목을 넣습니다. 항목은 DynamoDB로 전송되기 전에 클라이언트측에서 암호화되고 서명됩니다.  

```
var item = new Dictionary<String, AttributeValue>
{
    ["partition_key"] = new AttributeValue("BasicPutGetExample"),
    ["sort_key"] = new AttributeValue { N = "0" },
    ["attribute1"] = new AttributeValue("encrypt and sign me!"),
    ["attribute2"] = new AttributeValue("sign me!"),
    [":attribute3"] = new AttributeValue("ignore me!")
};

PutItemRequest putRequest = new PutItemRequest
{
    TableName = ddbTableName,
    Item = item
};

PutItemResponse putResponse = await ddb.PutItemAsync(putRequest);
```

## 하위 수준 사용 `DynamoDbItemEncryptor`
<a name="ddb-net-itemencryptor"></a>

다음 예제는 [AWS KMS 키링](use-kms-keyring.md)이 있는 하위 수준 `DynamoDbItemEncryptor`을 사용하여 테이블 항목을 직접 암호화하고 서명하는 방법을 보여줍니다. `DynamoDbItemEncryptor`는 DynamoDB 테이블에 항목을 배치하지 않습니다.

DynamoDB Enhanced Client에서 지원되는 모든 [키링](keyrings.md)을 사용할 수 있지만 가능하면 AWS KMS 키링 중 하나를 사용하는 것이 좋습니다.

**참고**  
하위 수준 `DynamoDbItemEncryptor`은 [검색 가능한 암호화](searchable-encryption.md)를 지원하지 않습니다. 하위 수준 AWS Database Encryption SDK for DynamoDB API를 사용하여 검색 가능한 암호화를 사용합니다.

**전체 코드 샘플**: [ItemEncryptDecryptExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/itemencryptor/ItemEncryptDecryptExample.cs) 참조

**1단계: AWS KMS 키링 생성**  
다음 예제에서는 `CreateAwsKmsMrkMultiKeyring`를 사용하여 대칭 암호화 KMS AWS KMS 키로 키링을 생성합니다. 이 `CreateAwsKmsMrkMultiKeyring` 방법을 사용하면 키링이 단일 리전 키와 다중 리전 키를 모두 올바르게 처리할 수 있습니다.  

```
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId };
var kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**2단계: 속성 작업 구성**  
다음 예제에서는 테이블 항목에 대한 샘플 [속성 작업을](concepts.md#crypt-actions) 나타내는 `attributeActionsOnEncrypt` 사전을 정의합니다.  
다음 예제에서는 속성을 로 정의하지 않습니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

```
var attributeActionsOnEncrypt = new Dictionary<String, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_ONLY, // The partition attribute must be SIGN_ONLY
    ["sort_key"] = CryptoAction.SIGN_ONLY, // The sort attribute must be SIGN_ONLY
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    [":attribute3"] = CryptoAction.DO_NOTHING
};
```

**3단계: 시그니처에서 제외할 속성을 정의합니다.**  
다음 예제에서는 모든 `DO_NOTHING` 속성이 고유한 접두사 "`:`“를 공유한다고 가정하고 이 접두사를 사용하여 허용된 서명되지 않은 속성을 정의합니다. 클라이언트는 접두사가 "`:`"인 모든 속성 이름이 서명에서 제외된다고 가정합니다. 자세한 내용은 [Allowed unsigned attributes](ddb-net-using.md#net-allowed-unauth) 단원을 참조하십시오.  

```
String unsignAttrPrefix = ":";
```

**4단계: `DynamoDbItemEncryptor` 구성 정의**  
다음 예제에서는 `DynamoDbItemEncryptor`의 구성을 정의합니다.  
이 예제에서는 DynamoDB 테이블 이름을 [논리적 테이블 이름](ddb-net-using.md#net-logical-table-name)으로 지정합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB의 암호화 구성](ddb-net-using.md#ddb-net-config-encrypt) 단원을 참조하십시오.  

```
var config = new DynamoDbItemEncryptorConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix
};
```

**5단계: `DynamoDbItemEncryptor` 생성**  
다음 예제에서는 **4단계**의 `config`를 사용하여 새 `DynamoDbItemEncryptor`을 만듭니다.  

```
var itemEncryptor = new DynamoDbItemEncryptor(config);
```

**6단계: 테이블 항목을 직접 암호화하고 서명합니다.**  
다음 예제에서는 `DynamoDbItemEncryptor`를 사용하여 항목을 직접 암호화하고 서명합니다. `DynamoDbItemEncryptor`는 DynamoDB 테이블에 항목을 배치하지 않습니다.  

```
var originalItem = new Dictionary<String, AttributeValue>
{
    ["partition_key"] = new AttributeValue("ItemEncryptDecryptExample"),
    ["sort_key"] = new AttributeValue { N = "0" },
    ["attribute1"] = new AttributeValue("encrypt and sign me!"),
    ["attribute2"] = new AttributeValue("sign me!"),
    [":attribute3"] = new AttributeValue("ignore me!")
};

var encryptedItem = itemEncryptor.EncryptItem(
    new EncryptItemInput { PlaintextItem = originalItem }
).EncryptedItem;
```

# DynamoDB용 AWS Database Encryption SDK를 사용하도록 기존 DynamoDB 테이블 구성
<a name="ddb-net-config-existing-table"></a>

DynamoDB용 .NET 클라이언트 측 암호화 라이브러리 버전 3.*x*를 사용하면 클라이언트 측 암호화를 위해 기존 Amazon DynamoDB 테이블을 구성할 수 있습니다. 이 주제에서는 채워진 기존 DynamoDB 테이블에 버전 3.*x*를 추가하기 위해 수행해야 하는 세 가지 단계에 대한 지침을 제공합니다.

## 1단계: 암호화된 항목 읽기 및 쓰기 준비
<a name="ddb-net-add-step1"></a>

다음 단계를 완료하여 AWS Database Encryption SDK 클라이언트가 암호화된 항목을 읽고 쓸 수 있도록 준비합니다. 다음 변경사항을 배포한 후에도 클라이언트는 계속해서 일반 텍스트 항목을 읽고 씁니다. 테이블에 기록된 새 항목을 암호화하거나 서명하지는 않지만 암호화된 항목이 나타나는 즉시 복호화할 수 있습니다. 이러한 변경으로 인해 클라이언트는 [새 항목의 암호화](#ddb-net-add-step2)를 시작할 수 있습니다. 다음 단계로 진행하기 전에 각 리더에 다음 변경 내용을 배포해야 합니다.

**1. [속성 작업](concepts.md#crypt-actions) 정의**  
객체 모델을 생성하여 암호화 및 서명할 속성 값, 서명만 할 속성 값, 무시할 속성 값을 정의합니다.  
기본적으로 프라이머리 키 속성은 서명되지만 암호화되지는 않으며(`SIGN_ONLY`) 다른 모든 속성은 암호화되고 서명됩니다(`ENCRYPT_AND_SIGN`).  
속성을 암호화하고 서명하도록 `ENCRYPT_AND_SIGN`을 지정합니다. 속성을 서명하되 암호화하지 않도록 `SIGN_ONLY`을 지정합니다. `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`를 지정하여 서명 및 속성을 지정하고 암호화 컨텍스트에 포함합니다. 서명하지 않으면 속성을 암호화할 수 없습니다. 속성을 무시하도록 `DO_NOTHING`을 지정합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB의 속성 작업](ddb-net-using.md#ddb-net-attribute-actions) 단원을 참조하십시오.  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

```
var attributeActionsOnEncrypt = new Dictionary<string, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_ONLY, // The partition attribute must be SIGN_ONLY
    ["sort_key"] = CryptoAction.SIGN_ONLY, // The sort attribute must be SIGN_ONLY
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    [":attribute3"] = CryptoAction.DO_NOTHING
};
```

**2. 서명에서 제외할 속성을 정의합니다.**  
다음 예제에서는 모든 `DO_NOTHING` 속성이 고유한 접두사 "`:`“를 공유한다고 가정하고 이 접두사를 사용하여 허용된 서명되지 않은 속성을 정의합니다. 클라이언트는 접두사가 "`:`"인 모든 속성 이름은 서명에서 제외된 것으로 간주합니다. 자세한 내용은 [Allowed unsigned attributes](ddb-net-using.md#net-allowed-unauth) 단원을 참조하십시오.  

```
const String unsignAttrPrefix = ":";
```

**3. [키링](keyrings.md) 생성**  
다음 예제에서는 [AWS KMS 키링](use-kms-keyring.md)을 생성합니다. AWS KMS 키링은 대칭 암호화 또는 비대칭 RSA AWS KMS keys 를 사용하여 데이터 키를 생성, 암호화 및 복호화합니다.  
이 예제에서는 `CreateMrkMultiKeyring`를 사용하여 대칭 암호화 KSM 키를 포함한 AWS KMS 키링을 생성합니다. 이 `CreateAwsKmsMrkMultiKeyring` 방법을 사용하면 키링이 단일 리전 키와 다중 리전 키를 모두 올바르게 처리할 수 있습니다.  

```
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId };
var kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**4. DynamoDB 테이블 암호화 구성 정의 **  
다음 예제는 이 DynamoDB 테이블의 암호화 구성을 나타내는 `tableConfigs` 맵을 정의합니다.  
이 예제에서는 DynamoDB 테이블 이름을 [논리적 테이블 이름](ddb-net-using.md#net-logical-table-name)으로 지정합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다.  
`FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT`을 일반 텍스트 오버라이드로 지정해야 합니다. 이 정책은 계속해서 일반 텍스트 항목을 읽고 쓰고, 암호화된 항목을 읽고, 클라이언트가 암호화된 항목을 쓸 수 있도록 준비시킵니다.  
테이블 암호화 구성에 포함된 값에 대한 자세한 내용은 섹션을 참조하세요[AWS Database Encryption SDK for DynamoDB의 암호화 구성](ddb-java-using.md#ddb-config-encrypt).  

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    PlaintextOverride = FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```

**5. 새 AWS SDK DynamoDB 클라이언트 생성**  
다음 예제에서는 **4단계**`TableEncryptionConfigs`의를 사용하여 새 AWS SDK DynamoDB 클라이언트를 생성합니다.  

```
var ddb = new Client.DynamoDbClient(
    new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs });
```

## 2단계: 암호화되고 서명된 항목 쓰기
<a name="ddb-net-add-step2"></a>

클라이언트가 암호화되고 서명된 항목을 작성할 수 있도록 테이블 암호화 구성에서 일반 텍스트 정책을 업데이트합니다. 다음 변경 사항을 배포하면 클라이언트는 **1단계**에서 구성한 속성 작업을 기반으로 새 항목을 암호화하고 서명합니다. 클라이언트는 일반 텍스트 항목과 암호화되고 서명된 항목을 읽을 수 있습니다.

[3단계](#ddb-net-add-step3)로 진행하기 전에 테이블의 기존 일반 텍스트 항목을 모두 암호화하고 서명해야 합니다. 기존 일반 텍스트 항목을 빠르게 암호화하기 위해 실행할 수 있는 단일 지표나 쿼리는 없습니다. 시스템에 가장 적합한 프로세스를 사용하세요. 예를 들어, 테이블을 천천히 스캔한 다음 정의한 속성 작업 및 암호화 구성을 사용하여 항목을 다시 쓰는 비동기 프로세스를 사용할 수 있습니다. 테이블의 일반 텍스트 항목을 식별하려면 암호화되고 서명될 때 AWS Database Encryption SDK가 항목에 추가하는 `aws_dbe_head` 및 `aws_dbe_foot` 속성이 포함되지 않은 모든 항목을 스캔하는 것이 좋습니다.

다음 예시에서는 **1단계**의 테이블 암호화 구성을 업데이트합니다. 일반 텍스트 오버라이드를 `FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT`로 업데이트해야 합니다. 이 정책은 일반 텍스트 항목을 계속 읽지만 암호화된 항목을 읽고 쓸 수도 있습니다. 업데이트된를 사용하여 새 AWS SDK DynamoDB 클라이언트를 생성합니다`TableEncryptionConfigs`.

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    PlaintextOverride = FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```

## 3단계: 암호화되고 서명된 항목만 읽기
<a name="ddb-net-add-step3"></a>

모든 항목을 암호화하고 서명한 후에는 클라이언트가 암호화되고 서명된 항목만 읽고 쓸 수 있도록 테이블 암호화 구성에서 일반 텍스트 재정의를 업데이트합니다. 다음 변경 사항을 배포하면 클라이언트는 **1단계**에서 구성한 속성 작업을 기반으로 새 항목을 암호화하고 서명합니다. 클라이언트는 암호화되고 서명된 항목만 읽을 수 있습니다.

다음 예시에서는 **2단계**의 테이블 암호화 구성을 업데이트합니다. `FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT`으로 일반 텍스트 재정의를 업데이트하거나 구성에서 일반 텍스트 정책을 제거할 수 있습니다. 클라이언트는 기본적으로 암호화되고 서명된 항목만 읽고 씁니다. 업데이트된를 사용하여 새 AWS SDK DynamoDB 클라이언트를 생성합니다`TableEncryptionConfigs`.

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    // Optional: you can also remove the plaintext policy from your configuration
    PlaintextOverride = FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```

# Rust
<a name="ddb-rust"></a>

이 주제에서는 DynamoDB용 Rust 클라이언트 측 암호화 라이브러리 버전 1.*x*를 설치하고 사용하는 방법을 설명합니다. DynamoDB용 AWS Database Encryption SDK를 사용한 프로그래밍에 대한 자세한 내용은 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에 있는 [Rust 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/)를 참조하세요.

 AWS Database Encryption SDK for DynamoDB의 모든 프로그래밍 언어 구현은 상호 운용 가능합니다.

**Topics**
+ [사전 조건](#ddb-rust-prerequisites)
+ [설치](#ddb-rust-install)
+ [Rust 클라이언트 사용](ddb-rust-using.md)

## 사전 조건
<a name="ddb-rust-prerequisites"></a>

DynamoDB용 Rust 클라이언트 측 암호화 라이브러리를 설치하기 전에 다음 사전 요구 사항이 있는지 확인합니다.

**Rust 및 Cargo 설치**  
[Rustup](https://rustup.rs/)[을](https://www.rust-lang.org/) 사용하여 현재 안정적인 Rust 릴리스를 설치합니다.  
rustup 다운로드 및 설치에 대한 자세한 내용은 카고 북의 [설치 절차를](https://doc.rust-lang.org/cargo/getting-started/installation.html) 참조하세요.

## 설치
<a name="ddb-rust-install"></a>

DynamoDB용 Rust 클라이언트 측 암호화 라이브러리는 Crates.io [aws-db-esdk](https://crates.io/crates/aws-db-esdk) 크레이트로 사용할 수 있습니다. 라이브러리 설치 및 빌드에 대한 자세한 내용은 aws-database-encryption-sdk-dynamodb GitHub 리포지토리의 [README.md](https://github.com/aws/aws-database-encryption-sdk-dynamodb/) 파일을 참조하세요.

**직접**  
DynamoDB용 Rust 클라이언트 측 암호화 라이브러리를 설치하려면 [aws-database-encryption-sdk-dynamodb](https://github.com/aws/aws-database-encryption-sdk-dynamodb/) GitHub 리포지토리를 복제하거나 다운로드합니다.

**최신 버전 설치**  
프로젝트 디렉터리에서 다음 Cargo 명령을 실행합니다.  

```
cargo add aws-db-esdk
```
또는 Cargo.toml에 다음 줄을 추가합니다.  

```
aws-db-esdk = "<version>"
```

# DynamoDB용 Rust 클라이언트 측 암호화 라이브러리 사용
<a name="ddb-rust-using"></a>

이 주제에서는 DynamoDB용 Rust 클라이언트 측 암호화 라이브러리 버전 1.*x*의 일부 함수 및 헬퍼 클래스에 대해 설명합니다.

DynamoDB용 Rust 클라이언트 측 암호화 라이브러리를 사용한 프로그래밍에 대한 자세한 내용은 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에 있는 [Rust 예제](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/)를 참조하세요.

**Topics**
+ [항목 암호화 도구](#ddb-rust-item-encryptors)
+ [속성 작업](#ddb-rust-attribute-actions)
+ [암호화 구성](#ddb-rust-config-encrypt)
+ [항목 업데이트](#ddb-rust-update-items)

## 항목 암호화 도구
<a name="ddb-rust-item-encryptors"></a>

코어에서 AWS Database Encryption SDK for DynamoDB는 항목 암호화 도구입니다. DynamoDB용 Rust 클라이언트 측 암호화 라이브러리 버전 1.*x*를 사용하여 다음과 같은 방법으로 DynamoDB 테이블 항목을 암호화, 서명, 확인 및 해독할 수 있습니다.

**DynamoDB API용 하위 수준 AWS 데이터베이스 암호화 SDK**  
[테이블 암호화 구성을](#ddb-rust-config-encrypt) 사용하여 DynamoDB `PutItem` 요청으로 클라이언트 측 항목을 자동으로 암호화하고 서명하는 DynamoDB 클라이언트를 구성할 수 있습니다.  
[검색 가능한](searchable-encryption.md) 암호화를 사용하려면 DynamoDB API용 하위 수준 AWS Database Encryption SDK를 사용해야 합니다.  
DynamoDB API용 하위 수준 AWS Database Encryption SDK를 사용하는 방법을 보여주는 예제는 GitHub의 aws-database-encryption-sdk-dynamodb 리포지토리에서 [basic\$1get\$1put\$1example.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/basic_get_put_example.rs)를 참조하세요.

**하위 수준 `DynamoDbItemEncryptor`**  
하위 수준 `DynamoDbItemEncryptor`에서는 DynamoDB를 호출하지 않고도 테이블 항목을 직접 암호화하고 서명 또는 복호화하고 확인합니다. DynamoDB `PutItem` 또는 `GetItem` 요청을 하지 않습니다. 예를 들어 하위 수준 `DynamoDbItemEncryptor`을 사용하여 이미 검색한 DynamoDB 항목을 직접 복호화하고 확인할 수 있습니다.  
하위 수준 `DynamoDbItemEncryptor`은 [검색 가능한 암호화](searchable-encryption.md)를 지원하지 않습니다.  
하위 수준를 사용하는 방법을 보여주는 예제는 GitHub의 aws-database-encryption-sdk-dynamodb[encryption-sdk-dynamodb 리포지토리에서 item\$1encrypt\$1decrypt.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/itemencryptor/item_encrypt_decrypt.rs)를 `DynamoDbItemEncryptor`참조하세요.

## AWS Database Encryption SDK for DynamoDB의 속성 작업
<a name="ddb-rust-attribute-actions"></a>

[속성 작업은](concepts.md#crypt-actions) 암호화 및 서명되는 속성 값, 서명만 되는 속성 값, 암호화 컨텍스트에 서명 및 포함되는 속성 값, 무시되는 속성 값을 결정합니다.

Rust 클라이언트를 사용하여 속성 작업을 지정하려면 객체 모델을 사용하여 속성 작업을 수동으로 정의합니다. 이름-값 페어가 속성 이름과 지정된 작업을 나타내는 `HashMap` 객체를 생성하여 속성 작업을 지정합니다.

속성을 암호화하고 서명하도록 `ENCRYPT_AND_SIGN`을 지정합니다. 속성을 서명하되 암호화하지 않도록 `SIGN_ONLY`을 지정합니다. 를 지정`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`하여 속성에 서명하고 암호화 컨텍스트에 포함합니다. 서명하지 않으면 속성을 암호화할 수 없습니다. 속성을 무시하도록 `DO_NOTHING`을 지정합니다.

파티션 및 정렬 속성은 `SIGN_ONLY` 또는 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. 속성을 로 정의하는 경우 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

**참고**  
속성 작업을 정의한 후에는 서명에서 제외할 속성을 정의해야 합니다. 나중에 서명되지 않은 새 속성을 더 쉽게 추가할 수 있도록 서명되지 않은 속성을 식별할 고유한 접두사(예: "`:`“)를 선택하는 것이 좋습니다. DynamoDB 스키마와 속성 작업을 정의할 때 `DO_NOTHING`로 표시된 모든 속성의 속성 이름에 이 접두사를 포함합니다.

다음 객체 모델은 Rust 클라이언트를 사용하여 `ENCRYPT_AND_SIGN`, `SIGN_ONLY``SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`, 및 `DO_NOTHING` 속성 작업을 지정하는 방법을 보여줍니다. 이 예제에서는 접두사 "`:`"를 사용하여 `DO_NOTHING` 속성을 식별합니다.

```
let attribute_actions_on_encrypt = HashMap::from([
    ("partition_key".to_string(), CryptoAction::SignOnly),
    ("sort_key".to_string(), CryptoAction::SignOnly),
    ("attribute1".to_string(), CryptoAction::EncryptAndSign),
    ("attribute2".to_string(), CryptoAction::SignOnly),
    (":attribute3".to_string(), CryptoAction::DoNothing),
]);
```

## AWS Database Encryption SDK for DynamoDB의 암호화 구성
<a name="ddb-rust-config-encrypt"></a>

 AWS Database Encryption SDK를 사용하는 경우 DynamoDB 테이블에 대한 암호화 구성을 명시적으로 정의해야 합니다. 암호화 구성에 필요한 값은 속성 작업을 수동으로 정의했는지 아니면 주석이 달린 데이터 클래스를 사용하여 정의했는지에 따라 달라집니다.

다음 코드 조각은 하위 수준 AWS Database Encryption SDK for DynamoDB API를 사용하여 DynamoDB 테이블 암호화 구성을 정의하고 고유한 접두사로 정의된 서명되지 않은 속성을 허용합니다.

```
let table_config = DynamoDbTableEncryptionConfig::builder()
    .logical_table_name(ddb_table_name)
    .partition_key_name("partition_key")
    .sort_key_name("sort_key")
    .attribute_actions_on_encrypt(attribute_actions_on_encrypt)
    .keyring(kms_keyring)
    .allowed_unsigned_attribute_prefix(UNSIGNED_ATTR_PREFIX)
    // Specifying an algorithm suite is optional
    .algorithm_suite_id(
        DbeAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384,
    )
    .build()?;

let table_configs = DynamoDbTablesEncryptionConfig::builder()
    .table_encryption_configs(HashMap::from([(ddb_table_name.to_string(), table_config)]))
    .build()?;
```

**논리적 테이블 이름**  
DynamoDB 테이블의 논리적 테이블 이름.  
논리적 테이블 이름은 테이블에 저장된 모든 데이터에 암호로 바인딩되어 DynamoDB 복원 작업을 간소화합니다. 암호화 구성을 처음 정의할 때 DynamoDB 테이블 이름을 논리적 테이블 이름으로 지정하는 것이 좋습니다. 항상 같은 논리적 테이블 이름을 지정해야 합니다. 복호화이 성공하려면 논리적 테이블 이름이 암호화에 지정된 이름과 일치해야 합니다. [백업에서 DynamoDB 테이블을 복원](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Restore.Tutorial.html)한 후 DynamoDB 테이블 이름이 변경되더라도 논리적 테이블 이름을 사용하면 복호화 작업에서 테이블을 계속 인식할 수 있습니다.

**허용된 서명되지 않은 속성**  
속성 작업에 `DO_NOTHING`로 표시된 속성.  
허용된 무서명 서명에서 제외되는 속성을 클라이언트에게 알려줍니다. 클라이언트는 다른 모든 속성이 서명에 포함되어 있다고 가정합니다. 그런 다음 레코드를 복호화할 때 클라이언트는 확인해야 할 속성과 지정한 허용된 무서명 속성 중에서 무시할 속성을 결정합니다. 허용된 무서명 속성에서는 속성을 제거할 수 없습니다.  
모든 `DO_NOTHING` 속성을 나열하는 배열을 만들어 무서명 허용 속성을 명시적으로 정의할 수 있습니다. `DO_NOTHING` 속성의 이름을 지정할 때 고유한 접두사를 지정하고 이 접두사를 사용하여 무서명 속성을 클라이언트에게 알릴 수도 있습니다. 고유한 접두사를 지정하는 것이 좋습니다. 이렇게 하면 나중에 새 `DO_NOTHING` 속성을 추가하는 프로세스가 단순해지기 때문입니다. 자세한 내용은 [데이터 모델 업데이트](ddb-update-data-model.md) 단원을 참조하십시오.  
모든 `DO_NOTHING` 속성에 접두사를 지정하지 않는 경우 클라이언트가 복호화 시 서명되지 않을 것으로 예상되는 모든 속성을 명시적으로 나열하는 `allowedUnsignedAttributes` 배열을 구성할 수 있습니다. 반드시 필요한 경우에만 허용된 서명되지 않은 속성을 명시적으로 정의해야 합니다.

**검색 구성(선택 사항)**  
`SearchConfig`는 [비컨 버전](using-beacons.md#beacon-version)을 정의합니다.  
[검색 가능한 암호화](searchable-encryption.md) 또는 [서명된 비컨](configure.md#signed-beacons)을 사용하려면 `SearchConfig`를 지정해야 합니다.

**알고리즘 제품군(선택 사항)**  
`algorithmSuiteId`은 AWS Database Encryption SDK가 사용하는 알고리즘 제품군을 정의합니다.  
대체 알고리즘 제품군을 명시적으로 지정하지 않는 한 AWS Database Encryption SDK는 [기본 알고리즘 제품군](supported-algorithms.md#recommended-algorithms)을 사용합니다. 기본 알고리즘 제품군은 키 도출, [디지털 서명](concepts.md#digital-sigs) 및 [키 커밋](concepts.md#key-commitment)과 함께 AES-GCM 알고리즘을 사용합니다. 기본 알고리즘 제품군이 대부분의 애플리케이션에 적합할 가능성이 높지만 대체 알고리즘 제품군을 선택할 수도 있습니다. 예를 들어, 일부 신뢰 모델은 디지털 서명이 없는 알고리즘 제품군으로 충분할 수 있습니다. AWS Database Encryption SDK가 지원하는 알고리즘 제품군에 대한 자세한 내용은 섹션을 참조하세요[AWS Database Encryption SDK에서 지원되는 알고리즘 제품군](supported-algorithms.md).  
[ECDSA 디지털 서명이 없는 AES-GCM 알고리즘 제품군을](supported-algorithms.md#other-algorithms) 선택하려면 테이블 암호화 구성에 다음 코드 조각을 포함합니다.  

```
.algorithm_suite_id(
    DbeAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384,
)
```

## AWS Database Encryption SDK로 항목 업데이트
<a name="ddb-rust-update-items"></a>

 AWS Database Encryption SDK는 암호화되거나 서명된 속성이 포함된 항목에 대해 [ddb:UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)을 지원하지 않습니다. 암호화되거나 서명된 속성을 업데이트하려면 [ddb:PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)을 사용해야 합니다. `PutItem` 요청에 기존 항목과 동일한 프라이머리 키를 지정하면 새 항목이 기존 항목을 완전히 대체합니다.

# 레거시 DynamoDB Encryption Client
<a name="legacy-dynamodb-encryption-client"></a>

2023년 6월 9일에 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. AWS Database Encryption SDK는 레거시 DynamoDB Encryption Client 버전을 계속 지원합니다. 이름 변경과 함께 변경된 클라이언트측 암호화 라이브러리의 여러 부분에 대한 자세한 내용은 [Amazon DynamoDB Encryption Client 이름 변경](DDBEC-rename.md) 섹션을 참조하세요.

DynamoDB용 Java 클라이언트측 암호화 라이브러리의 최신 버전으로 마이그레이션하려면 [버전 3.x로 마이그레이션](ddb-java-migrate.md) 섹션을 참조하세요.

**Topics**
+ [AWS DynamoDB용 Database Encryption SDK 버전 지원](#legacy-support)
+ [DynamoDB Encryption Client의 작동 방식](DDBEC-legacy-how-it-works.md)
+ [Amazon DynamoDB Encryption Client 개념](DDBEC-legacy-concepts.md)
+ [암호화 자료 공급자](crypto-materials-providers.md)
+ [Amazon DynamoDB Encryption Client에서 사용할 수 있는 프로그래밍 언어](programming-languages.md)
+ [데이터 모델 변경](data-model.md)
+ [DynamoDB Encryption Client 애플리케이션의 문제 해결](troubleshooting.md)

## AWS DynamoDB용 Database Encryption SDK 버전 지원
<a name="legacy-support"></a>

레거시 장의 주제에서는 DynamoDB Encryption Client for Java 버전 1.*x*\$12.*x*와 DynamoDB Encryption Client for Python 버전 1.*x*\$13.*x* 에 대한 정보를 제공합니다.

다음 표에는 Amazon DynamoDB에서 클라이언트측 암호화를 지원하는 언어 및 버전이 나와 있습니다.


| 프로그래밍 언어 | 버전 | SDK 메이저 버전 수명 주기 단계 | 
| --- | --- | --- | 
|  Java  |  버전 1.*x*  |  [지원 종료 단계](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle), 2022년 7월부터 적용  | 
|  Java  |  버전 2.*x*  |  [일반 가용성](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)(GA)  | 
|  Java  |  버전 3.*x*  |  [일반 가용성](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)(GA)  | 
|  Python  |  버전 1.*x*  |  [지원 종료 단계](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle), 2022년 7월부터 적용  | 
|  Python  |  버전 2.*x*  |  [지원 종료 단계](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle), 2022년 7월부터 적용  | 
|  Python  |  버전 3.*x*  |  [일반 가용성](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)(GA)  | 

# DynamoDB Encryption Client의 작동 방식
<a name="DDBEC-legacy-how-it-works"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

DynamoDB Encryption Client는 DynamoDB에 저장하는 데이터를 보호하도록 특별히 설계되었습니다. 라이브러리에는 변경 없이 확장하거나 사용할 수 있는 보안 구현이 포함되어 있습니다. 그리고 대부분의 요소는 추상 요소로 표현되므로 호환되는 사용자 지정 구성 요소를 생성하고 사용할 수 있습니다.

**테이블 항목 암호화 및 서명**

DynamoDB Encryption Client의 핵심에는 테이블 항목을 암호화, 서명, 확인 및 복호화하는 *항목 암호화 도구*가 있습니다. 항목 암호화 도구는 테이블 항목에 대한 정보와 암호화 및 서명할 항목에 대한 지침을 사용합니다. 또한 암호화 자료와 이 자료를 사용하는 방법에 대한 지침을 사용자가 선택 및 구성하는 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)에서 가져옵니다.

다음 다이어그램은 이 프로세스에 대한 개략적인 보기를 보여줍니다.

![\[DynamoDB Encryption Client에서 항목 암호화 및 서명\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/arch-encrypt.png)


테이블 항목을 암호화하고 서명하려면 DynamoDB Encryption Client에 다음이 필요합니다.
+ **테이블에 대한 정보입니다.** 사용자가 제공하는 [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)에서 테이블에 대한 정보를 가져옵니다. 일부 도우미는 DynamoDB에서 필요한 정보를 가져오고 DynamoDB 암호화 컨텍스트를 생성합니다.
**참고**  
*DynamoDB Encryption Client의 DynamoDB 암호화 컨텍스트*는 AWS Key Management Service (AWS KMS) 및의 *암호화 컨텍스트*와 관련이 없습니다 AWS Encryption SDK. DynamoDB 
+ **암호화 및 서명할 속성.** 제공하는 [속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)에서 이 정보를 가져옵니다.
+ **암호화 및 서명 키를 포함하는 암호화 자료.** 이러한 자료는 선택 및 구성하는 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)에서 가져옵니다.
+ **항목 암호화 및 서명 지침**. CMP는 암호화 및 서명 알고리즘을 비롯하여 암호화 자료 사용 관련 지침을 [실제 자료 설명](DDBEC-legacy-concepts.md#legacy-material-description)에 추가합니다.

[항목 암호화 도구](DDBEC-legacy-concepts.md#item-encryptor)는 이러한 요소를 모두 사용하여 항목을 암호화하고 서명합니다. 또한 항목 암호화 도구는 암호화 및 서명 지침(실제 자료 설명)을 포함하는 [자료 설명 속성](DDBEC-legacy-concepts.md#legacy-material-description)과, 서명을 포함하는 속성, 이 두 가지 속성을 항목에 추가합니다. 항목 암호화 도구와 직접 상호 작용하거나 항목 암호화 도구와 상호 작용하는 도우미 기능을 사용하여 안전한 기본 동작을 구현할 수 있습니다.

결과는 암호화되고 서명된 데이터를 포함하는 DynamoDB 항목입니다.

**테이블 항목 확인 및 복호화**

다음 다이어그램에 나와 있듯이 이러한 구성 요소는 함께 작동하여 항목을 확인하고 복호화합니다.

![\[DynamoDB Encryption Client의 항목 확인 및 복호화\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/arch-decrypt.png)


항목을 확인하고 복호화하려면 DynamoDB Encryption Client에 다음과 같이 동일한 구성 요소, 동일한 구성의 구성 요소 또는 항목 복호화을 위해 특별히 설계된 구성 요소가 필요합니다.
+ [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)의 **테이블에 대한 정보**입니다.
+ **확인하고 복호화할 속성.** 이러한 정보는 [속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)에서 가져옵니다.
+ **확인 및 복호화 키를 포함하는 복호화 자료**. 이러한 정보는 사용자가 선택 및 구성하는 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)에서 가져옵니다.

  암호화된 항목에는 이를 암호화하는 데 사용된 CMP 레코드가 포함되어 있지 않습니다. 동일한 CMP, 동일한 구성의 CMP 또는 항목을 복호화하도록 설계된 CMP를 제공해야 합니다.
+ **항목의 암호화 및 서명된 방식에 대한 정보**(암호화 및 서명 알고리즘 포함). 클라이언트는 항목의 [자료 설명 속성](DDBEC-legacy-concepts.md#legacy-material-description)에서 이러한 정보를 가져옵니다.

[항목 암호화 도구](DDBEC-legacy-concepts.md#item-encryptor)는 이러한 요소를 모두 사용하여 항목을 확인 및 복호화합니다. 또한 자료 설명 및 서명 속성도 제거됩니다. 결과는 일반 텍스트 DynamoDB 항목입니다.

# Amazon DynamoDB Encryption Client 개념
<a name="DDBEC-legacy-concepts"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

이 주제에서는 Amazon DynamoDB Encryption Client에서 사용되는 개념과 용어에 대해 설명합니다.

DynamoDB Encryption Client의 구성 요소가 어떻게 상호 작용하는지에 대해 알아보려면 [DynamoDB Encryption Client의 작동 방식](DDBEC-legacy-how-it-works.md) 섹션을 참조하세요.

**Topics**
+ [암호화 자료 공급자(CMP)](#concept-material-provider)
+ [항목 암호화 도구](#item-encryptor)
+ [속성 작업](#legacy-attribute-actions)
+ [자료 설명](#legacy-material-description)
+ [DynamoDB 암호화 컨텍스트](#legacy-encryption-context)
+ [공급자 스토어](#provider-store)

## 암호화 자료 공급자(CMP)
<a name="concept-material-provider"></a>

DynamoDB Encryption Client를 구현할 때 가장 먼저 해야 할 작업 중 하나는 [암호화 자료 공급자(CMP)(*암호화 자료 공급*자라고도 함)를 선택](crypto-materials-providers.md)하는 것입니다. 사용자의 선택에 따라 나머지 구현의 상당 부분이 결정됩니다.

*암호화 자료 공급자*(CMP)는 [항목 암호화 도구](#item-encryptor)에서 테이블 항목을 암호화 및 서명하는 데 사용하는 암호화 자료를 수집, 조합 및 반환합니다. CMP는 사용할 암호화 알고리즘과 암호화 및 서명 키를 생성하고 보호하는 방법을 결정합니다.

CMP는 항목 암호화와 상호 작용합니다. 항목 암호화 도구는 CMP에 암호화 또는 복호화 자료를 요청하고, CMP는 이를 항목 암호화 도구에 반환합니다. 그러면 항목 암호화 도구는 암호화 자료를 사용하여 항목을 암호화하고 서명하거나 확인 및 복호화합니다.

CMP는 클라이언트를 구성할 때 지정합니다. 호환되는 사용자 지정 CMP를 만들거나 라이브러리에 있는 여러 CMP 중 하나를 사용할 수 있습니다. 대부분의 CMP는 여러 프로그래밍 언어에 사용할 수 있습니다.

## 항목 암호화 도구
<a name="item-encryptor"></a>

*항목 암호화 도구*는 DynamoDB Encryption Client에 대한 암호화 작업을 수행하는 하위 수준 구성 요소입니다. 이 도구는 [암호화 자료 공급자](#concept-material-provider)(CMP)로부터 암호화 자료를 요청한 다음, CMP에서 반환하는 자료를 사용하여 테이블 항목을 암호화 및 서명하거나 확인 및 복호화합니다.

항목 암호화 도구와 직접 상호 작용하거나 라이브러리에서 제공하는 헬퍼를 사용할 수 있습니다. 예를 들면 DynamoDB Encryption Client for Java에는 `DynamoDBEncryptor` 항목 암호화 도구와 직접 상호 작용하지 않고 `DynamoDBMapper`과 함께 사용할 수 있는 `AttributeEncryptor` 헬퍼 클래스가 포함되어 있습니다. Python 라이브러리에는 항목 암호기와 상호 작용하는 `EncryptedTable`, `EncryptedClient`, 및 `EncryptedResource` 헬퍼 클래스가 포함되어 있습니다.

## 속성 작업
<a name="legacy-attribute-actions"></a>

*속성 작업*은 항목의 각 속성에 대해 수행할 작업을 항목 암호화 도구에 알려줍니다.

속성 작업 값은 다음 중 하나일 수 있습니다.
+ **암호화 및 서명** - 속성 값을 암호화합니다. 항목 서명에 속성(이름 및 값)을 포함합니다.
+ **서명만** - 항목 서명에 속성을 포함합니다.
+ **아무 작업 안 함** - 속성을 암호화거나 서명하지 않습니다.

중요한 데이터를 저장할 수 있는 속성의 경우 **Encrypt and sign(암호화 및 서명)**을 사용합니다. 기본 키 속성(파티션 키 및 정렬 키)의 경우 **Sign only(서명만)**를 사용합니다. [자료 설명 속성](#legacy-material-description) 및 서명 속성은 서명되거나 암호화되지 않습니다. 이러한 속성에 대해 속성 작업을 지정할 필요가 없습니다.

속성 작업을 신중하게 선택합니다. 확실하지 않은 경우 **Encrypt and sign(암호화 및 서명)**을 사용합니다. DynamoDB Encryption Client를 사용하여 테이블 항목을 보호한 후 속성에 대한 작업을 변경하면 서명 유효성 검사 오류가 발생할 위험이 있습니다. 자세한 내용은 [데이터 모델 변경](data-model.md)을 참조하세요.

**주의**  
기본 키 속성은 암호화하지 마십시오. 일반 텍스트로 남겨 두어야 DynamoDB에서 전체 테이블 스캔을 실행하지 않고 해당 항목을 찾을 수 있습니다.

[DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)에서 프라이머리 키 속성이 식별되는 경우 이러한 속성을 암호화하려 할 때 클라이언트에서 오류가 발생합니다.

속성 작업을 지정하는 데 사용하는 기법은 프로그래밍 언어마다 다릅니다. 사용하는 도우미 클래스에만 해당될 수도 있습니다.

자세한 내용은 프로그래밍 언어 설명서를 참조하세요.
+ [Python](python-using.md#python-attribute-actions)
+ [Java](java-using.md#attribute-actions-java)

## 자료 설명
<a name="legacy-material-description"></a>

암호화된 테이블 항목에 대한 *자료 설명*은 테이블 항목의 암호화 및 서명 방법에 대한 정보(예: 암호화 알고리즘)로 구성됩니다. [암호화 자료 공급자](#concept-material-provider)(CMP)는 암호화 및 서명을 위해 암호화 자료를 결합할 때 자료 설명을 기록합니다. 나중에 항목을 확인하고 복호화하기 위해 암호화 자료를 조립해야 할 때 자료 설명을 가이드로 사용합니다.

DynamoDB Encryption Client에서 자료 설명은 다음과 같은 세 가지 관련 요소를 참조하세요.

**요청한 자료 설명**  
특정 [암호화 자료 공급자](#concept-material-provider)(CMP)에서는 암호화 알고리즘 같은 고급 옵션을 지정할 수 있습니다. 선택 사항을 지정하려면 테이블 항목을 암호화하기 위해 요청의 [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context) 자료 설명 속성에 이름-값 페어를 추가합니다. 이 요소를 *요청한 자료 설명*이라고 합니다. 요청된 자료 설명의 유효한 값은 선택한 CMP에 의해 정의됩니다.  
자료 설명은 보안 기본값보다 우선할 수 있으므로 요청된 자료 설명을 사용해야 하는 설득력 있는 이유가 없는 한 생략하는 것이 좋습니다.

**실제 자료 설명**  
[암호화 자료 공급자](#concept-material-provider)(CMP)에서 반환하는 자료 설명을 *실제 자료 설명*이라고 합니다. 여기에는 CMP가 암호화 자료를 조합할 때 사용한 실제 값이 설명되어 있습니다. 일반적으로 요청된 자료 설명(있는 경우)과 추가 및 변경 내용으로 구성됩니다.

**자료 설명 속성**  
클라이언트는 암호화된 항목의 *자료 설명 속성*에 실제 자료 설명을 저장합니다. 자료 설명 속성 이름은 `amzn-ddb-map-desc`이고 속성 값은 실제 자료 설명입니다. 클라이언트는 자료 설명 속성의 값을 사용하여 항목을 확인하고 복호화합니다.

## DynamoDB 암호화 컨텍스트
<a name="legacy-encryption-context"></a>

*DynamoDB 암호화 컨텍스트*는 테이블 및 항목에 대한 정보를 [암호화 자료 공급자](#concept-material-provider)(CMP)에게 제공합니다. 고급 구현에서는 DynamoDB 암호화 컨텍스트에 [요청한 자료 설명](#legacy-material-description)이 포함될 수 있습니다.

테이블 항목을 암호화하는 경우 DynamoDB 암호화 컨텍스트는 암호화된 속성 값에 암호로 바인딩됩니다. 복호화할 때 DynamoDB 암호화 컨텍스트가 암호화에 사용된 DynamoDB 암호화 컨텍스트와 대/소문자가 정확히 일치하지 않으면 복호화 작업이 실패합니다. [항목 암호화 도구](#item-encryptor)와 직접 상호 작용하는 경우 암호화 또는 복호화 메서드를 호출할 때 DynamoDB 암호화 컨텍스트를 제공해야 합니다. 대부분의 헬퍼는 DynamoDB 암호화 컨텍스트를 자동으로 생성합니다.

**참고**  
*DynamoDB Encryption Client의 DynamoDB 암호화 컨텍스트*는 AWS Key Management Service (AWS KMS) 및의 *암호화 컨텍스트*와 관련이 없습니다 AWS Encryption SDK. DynamoDB 

DynamoDB 암호화 컨텍스트에는 다음 필드가 포함될 수 있습니다. 모든 필드와 값은 선택 사항입니다.
+ 테이블 이름
+ 파티션 키 이름
+ 정렬 키 이름
+ 속성 이름-값 페어
+ [요청한 자료 설명](#legacy-material-description)

## 공급자 스토어
<a name="provider-store"></a>

*공급자 스토어*는 [암호화 자료 공급자](#concept-material-provider)(CMP)를 반환하는 구성 요소입니다. 공급자 스토어는 CMP를 생성하거나 다른 공급자 스토어와 같은 다른 소스에서 가져올 수 있습니다. 공급자 스토어는 생성한 CMP 버전을 영구 스토어에 저장합니다. 영구 스토어에는 저장된 각 CMP가 요청자의 자료 이름 및 버전 번호로 식별됩니다.

DynamoDB Encryption Client의 [Most Recent Provider](most-recent-provider.md)는 공급자 스토어에서 CMP를 가져오지만, 공급자 스토어를 사용하여 모든 구성 요소에 CMP를 제공할 수 있습니다. 각 Most Recent Provider는 공급자 스토어 하나와 연결되지만, 공급자 스토어 하나는 여러 요청자의 여러 공급자로 CMP를 제공할 수 있습니다.

공급자 스토어는 요청 시 새 버전의 CMP를 생성하고 새 버전과 기존 버전을 반환합니다. 또한 해당 자료얼 이름의 최신 버전 번호도 반환합니다. 이를 통해 요청자는 공급자 스토어에 요청할 수 있는 새 버전의 CMP가 있을 때 이를 알 수 있습니다.

DynamoDB Encryption Client에는 DynamoDB에 저장되고 내부 DynamoDB Encryption Client를 사용하여 암호화된 키로 래핑된 CMP를 생성하는 공급자 스토어인 [MetaStore](most-recent-provider.md#about-metastore)가 포함되어 있습니다.

**자세히 알아보기:**
+ 공급자 스토어: [Java](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/store/ProviderStore.html), [Python](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/src/dynamodb_encryption_sdk/material_providers/store/__init__.py)
+ MetaStore: [Java](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/store/MetaStore.html), [Python](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/materials_providers/metastore.html#module-dynamodb_encryption_sdk.material_providers.store.meta)

# 암호화 자료 공급자
<a name="crypto-materials-providers"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

DynamoDB Encryption Client를 사용할 때 내려야 하는 가장 중요한 결정 중 하나는 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)를 선택하는 것입니다. CMP는 암호화 자료를 조합하여 항목 암호화 도구에 반환합니다. 또한 암호화 및 서명 키의 생성 방법, 각 항목에 대해 새로운 키 자료를 생성하거나 재사용할지 여부, 사용되는 암호화 및 서명 알고리즘도 결정합니다.

DynamoDB Encryption Client 라이브러리에 제공된 구현에서 CMP를 선택하거나 호환 가능한 사용자 지정 CMP를 구축할 수 있습니다. CMP 선택은 사용하는 [프로그래밍 언어](programming-languages.md)에 따라 달라질 수도 있습니다.

이 주제에서는 가장 일반적인 CMP를 설명하고 애플리케이션에 가장 적합한 CMP를 선택하는 데 도움이 되는 몇 가지 조언을 제공합니다.

**Direct KMS Materials Provider**  
Direct KMS Materials Provider는 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS)를 암호화되지 않은 상태로 두는 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)에 따라 테이블 항목을 보호합니다. 애플리케이션에서 암호화 자료를 생성하거나 관리할 필요가 없습니다. AWS KMS key 를 사용하여 각 항목에 대한 고유한 암호화 및 서명 키를 생성하기 때문에이 공급자는 항목을 암호화하거나 해독할 AWS KMS 때마다를 호출합니다.  
 AWS KMS 를 사용하고 트랜잭션당 하나의 AWS KMS 호출이 애플리케이션에 유용한 경우이 공급자가 좋은 선택입니다.  
자세한 내용은 [Direct KMS Materials Provider](direct-kms-provider.md)을 참조하세요.

**래핑된 자료 공급자(래핑된 CMP)**  
래핑된 자료 공급자(래핑된 CMP)는 DynamoDB Encryption Client 외부에서 래핑 및 서명 키를 생성 및 관리할 수 있도록 해줍니다.  
래핑된 CMP는 각 항목에 대해 고유한 암호화 키를 생성합니다. 그런 다음 사용자가 제공한 래핑(또는 언래핑) 및 서명 키를 사용합니다. 따라서 래핑 및 서명 키의 생성 방법과 각 항목에 고유한지 또는 재사용되는지를 결정합니다. 래핑된 CMP는 암호화 자료를 사용하지 않고 안전하게 관리할 AWS KMS 수 있는 애플리케이션을 위한 [Direct KMS Provider](direct-kms-provider.md)의 안전한 대안입니다.  
자세한 내용은 [Wrapped Materials Provider](wrapped-provider.md)을 참조하세요.

**Most Recent Provider**  
*Most Recent Provider*는 [공급자 스토어](DDBEC-legacy-concepts.md#provider-store)와 함께 작동하도록 설계된 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)입니다. 공급자 스토어에서 CMP를 가져오고 CMP에서 반환한 암호화 자료를 가져옵니다. Most Recent Provider는 일반적으로 각각의 CMP를 사용하여 암호화 자료에 대한 여러 요청을 충족하지만, 공급자 스토어의 기능을 사용하여 자료의 재사용 범위를 제어하고, CMP 교체 빈도를 결정하며, Most Recent Provider를 변경하지 않고 사용되는 CMP 유형도 변경합니다.  
호환되는 모든 공급자 스토어에서 Most Recent Provider를 사용할 수 있습니다. DynamoDB Encryption Client에는 래핑된 CMP를 반환하는 공급자 스토어인 MetaStore가 포함됩니다.  
Most Recent Provider는 관련 암호화 소스에 대한 호출을 최소화해야 하는 애플리케이션과, 보안 요구 사항을 위반하지 않으면서 일부 암호화 자료를 재사용할 수 있는 애플리케이션에 적합합니다. 예를 들어 항목을 암호화하거나 해독할 AWS KMS 때마다를 호출하지 않고 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS)의 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)에서 암호화 자료를 보호할 수 있습니다.  
자세한 내용은 [Most Recent Provider](most-recent-provider.md)을 참조하세요.

**Static Materials Provider**  
Static Materials Provider는 테스트, 개념 증명 데모 및 레거시 호환성 목적으로 설계되었습니다. 각 항목에 대해 고유한 암호화 자료를 생성하지는 않습니다. 입력한 것과 동일한 암호화 및 서명 키를 반환하며, 이러한 키는 테이블 항목을 암호화, 복호화 및 서명하는 데 직접 사용됩니다.  
Java 라이브러리의 [Asymmetric Static Provider](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/AsymmetricStaticProvider.html)는 Static Provider가 아닙니다. 단순히 [Wrapped CMP](wrapped-provider.md)에 대한 대체 생성자를 제공할 뿐입니다. 프로덕션 환경에서는 안전하지만 가능하면 래핑된 CMP를 직접 사용해야 합니다.

**Topics**
+ [Direct KMS Materials Provider](direct-kms-provider.md)
+ [Wrapped Materials Provider](wrapped-provider.md)
+ [Most Recent Provider](most-recent-provider.md)
+ [Static Materials Provider](static-provider.md)

# Direct KMS Materials Provider
<a name="direct-kms-provider"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

*Direct KMS Materials Provider*(Direct KMS Provider)는 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS)을 암호화되지 않은 상태로 유지하지 않는 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)에 따라 테이블 항목을 보호합니다. 이 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)는 각 테이블 항목에 대해 고유한 암호화 키 및 서명 키를 반환합니다. 이를 위해 항목을 암호화하거나 해독할 AWS KMS 때마다가 호출됩니다.

DynamoDB 항목을 높은 빈도로 대규모로 처리하는 경우 AWS KMS [requests-per-second 수 제한을](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html#requests-per-second) 초과하여 처리가 지연될 수 있습니다. 제한을 초과해야 하는 경우 [AWS Support 센터](https://console.aws.amazon.com/support/home)에서 사례를 생성합니다. [Most Recent Provider](most-recent-provider.md)와 같이 키 재사용이 제한된 암호화 자료 공급자를 사용하는 것도 고려해 볼 수 있습니다.

Direct KMS Provider를 사용하려면 호출자에게 [에서 AWS 계정](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/) [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) AWS KMS key및 [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) 작업을 호출할 수 있는 하나 이상의 및 권한이 있어야 합니다 AWS KMS key. AWS KMS key 는 대칭 암호화 키여야 합니다. DynamoDB Encryption Client는 비대칭 암호화를 지원하지 않습니다. [DynamoDB 글로벌 테이블](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)을 사용하는 경우 [AWS KMS 다중 리전 키](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)를 지정하는 것이 좋습니다. 자세한 내용은 [사용 방법](#provider-kms-how-to-use)을 참조하세요.

**참고**  
Direct KMS Provider를 사용하면 기본 키 속성의 이름과 값이 [AWS KMS 암호화 컨텍스트](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context) 및 관련 AWS KMS 작업 AWS CloudTrail 로그에 일반 텍스트로 표시됩니다. 그러나 DynamoDB Encryption Client는 암호화된 어떤 속성 값도 일반 텍스트로 노출하지 않습니다.

Direct KMS Provider는 DynamoDB Encryption Client가 지원하는 여러 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP) 중 하나입니다. 기타 CMP에 대한 자세한 내용은 [암호화 자료 공급자](crypto-materials-providers.md) 섹션을 참조하세요.

**예제 코드는 다음을 참조하십시오.**
+ Java: [AwsKmsEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedItem.java)
+ Python: [aws-kms-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_table.py), [aws-kms-encrypted-item](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_item.py)

**Topics**
+ [사용 방법](#provider-kms-how-to-use)
+ [작동 방식](#provider-kms-how-it-works)

## 사용 방법
<a name="provider-kms-how-to-use"></a>

Direct KMS Provider를 생성하려면 키 ID 파라미터를 사용하여 계정에 대칭 암호화 [KMS 키](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)를 지정합니다. 키 ID 파라미터의 값은 AWS KMS key의 키 ID, 키 ARN, 별칭 이름 또는 별칭 ARN일 수 있습니다. 키 식별자에 대한 자세한 내용은 *AWS Key Management Service 개발자 가이드*의 [키 식별자](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)를 참조하세요.

Direct KMS Provider에는 대칭 암호화 KMS 키가 필요합니다. 비대칭 KMS 키를 사용할 수 없습니다. 그러나 다중 리전 KMS 키, 가져온 키 자료가 있는 KMS 키 또는 사용자 지정 키 스토어의 KMS 키를 사용할 수 있습니다. KMS 키에 대한 [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) 및 [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) 권한이 있어야 합니다. 따라서 관리형 또는 AWS 소유 KMS 키가 아닌 고객 AWS 관리형 키를 사용해야 합니다.

DynamoDB Encryption Client for Python은 키 ID 파라미터 값이 포함된 경우 해당 리전 AWS KMS 에서 호출할 리전을 결정합니다. 그렇지 않으면 AWS KMS 클라이언트에서 리전을 지정하거나에서 구성하는 리전을 사용합니다 AWS SDK for Python (Boto3). Python의 리전 선택에 대한 자세한 내용은 Python용 AWS SDK(Boto3) API 참조의 [구성을](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html) 참조하세요.

지정한 클라이언트에 리전이 포함된 경우 Java용 DynamoDB 암호화 클라이언트는 클라이언트의 리전 AWS KMS AWS KMS 에서 호출할 리전을 결정합니다. 그렇지 않으면 AWS SDK for Java에서 구성한 리전을 사용합니다. 의 리전 선택에 대한 자세한 내용은 AWS SDK for Java 개발자 안내서의 [AWS 리전 선택을](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-region-selection.html) AWS SDK for Java참조하세요.

------
#### [ Java ]

```
// Replace the example key ARN and Region with valid values for your application
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);
```

------
#### [ Python ]

다음 예에서는 ARN 키를 사용하여 AWS KMS key를 지정합니다. 키 식별자에이 포함되지 않은 경우 AWS 리전 DynamoDB Encryption Client는 구성된 Botocore 세션에서 리전을 가져오거나 Boto 기본값에서 리전을 가져옵니다.

```
# Replace the example key ID with a valid value
kms_key = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key)
```

------

[Amazon DynamoDB 글로벌 테이블](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)을 사용하는 경우 AWS KMS 다중 리전 키로 데이터를 암호화하는 것이 좋습니다. 다중 리전 키는 키 ID와 키 구성 요소가 동일하기 때문에 서로 교환하여 사용할 수 AWS 리전 있는 다른 AWS KMS keys 에 있습니다. 자세한 내용을 알아보려면 *AWS Key Management Service 개발자 안내서*의 [다중 리전 키 사용](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)을 참조하세요.

**참고**  
글로벌 테이블 [버전 2017.11.29](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html)를 사용하는 경우 예약된 복제 필드가 암호화되거나 서명되지 않도록 속성 작업을 설정해야 합니다. 자세한 내용은 [이전 버전 글로벌 테이블 관련 문제](troubleshooting.md#fix-global-tables)을 참조하세요.

DynamoDB Encryption Client에서 다중 리전 키를 사용하려면 다중 리전 키를 생성하여 애플리케이션이 실행되는 리전에 복제합니다. 그런 다음 DynamoDB Encryption Client가 AWS KMS을 호출하는 리전의 다중 리전 키를 사용하도록 Direct KMS Provider를 구성합니다.

다음 예제에서는 다중 리전 키를 사용하여 미국 동부(버지니아 북부)(us-east-1) 리전의 데이터를 암호화하고 미국 서부(오레곤)(us-west-2) 리전에서 이를 복호화하도록 DynamoDB Encryption Client를 구성합니다.

------
#### [ Java ]

이 예제에서 DynamoDB Encryption Client는 AWS KMS 클라이언트의 리전 AWS KMS 에서 호출할 리전을 가져옵니다. 이 `keyArn` 값은 동일한 리전의 다중 리전 키를 식별합니다.

```
// Encrypt in us-east-1

// Replace the example key ARN and Region with valid values for your application
final String usEastKey = 'arn:aws:kms:us-east-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
final String region = 'us-east-1'
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, usEastKey);
```

```
// Decrypt in us-west-2

// Replace the example key ARN and Region with valid values for your application
final String usWestKey = 'arn:aws:kms:us-west-2:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
final String region = 'us-west-2'
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, usWestKey);
```

------
#### [ Python ]

이 예제에서 DynamoDB Encryption Client는 키 ARN의 리전 AWS KMS 에서 호출할 리전을 가져옵니다.

```
# Encrypt in us-east-1

# Replace the example key ID with a valid value
us_east_key = 'arn:aws:kms:us-east-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=us_east_key)
```

```
# Decrypt in us-west-2

# Replace the example key ID with a valid value
us_west_key = 'arn:aws:kms:us-west-2:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=us_west_key)
```

------

## 작동 방식
<a name="provider-kms-how-it-works"></a>

Direct KMS Provider는 다음 다이어그램에서처럼 사용자가 지정하는 AWS KMS key 에 의해 보호되는 암호화 및 서명 키를 반환합니다.

![\[DynamoDB Encryption Client에서 Direct KMS Provider의 입력, 처리 및 출력\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/directKMS.png)

+ 암호화 자료를 생성하기 위해 Direct KMS Provider는 AWS KMS key 사용자가 지정한 [를 사용하여 각 항목에 대해 고유한 데이터 키를 생성](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) AWS KMS 하도록 요청합니다. 이 공급자는 [데이터 키](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys)의 일반 텍스트 복사본에서 항목의 암호화 및 서명 키를 추출한 다음 항목의 [자료 설명 속성](DDBEC-legacy-concepts.md#legacy-material-description)에 저장된 암호화된 데이터 키와 함께 암호화 및 서명 키를 반환합니다.

  항목 암호화기는 암호화 및 서명 키를 사용하여 가능한 한 빨리 메모리에서 암호화 및 서명 키를 제거합니다. 파생된 데이터 키의 암호화된 복사본만 암호화된 항목에 저장됩니다.
+ 복호화 자료를 생성하기 위해 Direct KMS Provider는 암호화된 데이터 키를 복호화 AWS KMS 하도록 요청합니다. 그런 다음 일반 텍스트 데이터 키에서 확인 및 서명 키를 추출하여 항목 암호화 도구에 반환합니다.

  항목 암호화기는 항목을 확인하고 확인에 성공하면 암호화된 값을 복호화합니다. 그런 다음 가능한 빨리 메모리에서 키를 제거합니다.

### 암호화 자료 가져오기
<a name="direct-kms-get-encryption-materials"></a>

이 단원에서는 [항목 암호화 도구](DDBEC-legacy-concepts.md#item-encryptor)에서 암호화 자료 요청 수신 시 Direct KMS Provider의 입력, 출력 및 처리에 대해 자세히 설명합니다.

**입력**(애플리케이션에서)
+ 의 키 ID입니다 AWS KMS key.

**입력**(항목 암호화 도구에서)
+ [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)

**출력**(항목 암호화 도구로)
+ 암호화 키(일반 텍스트)
+ 서명 키
+ [실제 자료 설명](DDBEC-legacy-concepts.md#legacy-material-description): 이러한 값은 클라이언트가 항목에 추가하는 자료 설명 속성에 저장됩니다.
  + amzn-ddb-env-key: 로 암호화된 Base64-encoded 데이터 키 AWS KMS key
  + amzn-ddb-env-alg: 암호화 알고리즘, 기본값은 [AES/256](https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/archived-crypto-projects/aes-development)
  + amzn-ddb-sig-alg: 서명 알고리즘, 기본값은 [HmacSHA256/256](https://en.wikipedia.org/wiki/HMAC)
  + amzn-ddb-wrap-alg: kms

**처리**

1. 다이렉트 KMS 공급자는 지정된 AWS KMS 를 사용하여 항목에 대한 고유한 데이터 키를 AWS KMS key 생성하라는 요청을 보냅니다. [https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) 이 작업은 일반 텍스트 키와 AWS KMS key로 암호화된 복사본을 반환합니다. 이 자료를 *초기 키 자료*라고 합니다.

   이 요청은 [AWS KMS 암호화 컨텍스트](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)에 다음 값을 일반 텍스트로 포함합니다. 이러한 비밀이 아닌 값은 암호화된 개체에 암호화 방식으로 바인딩되므로 복호화 시 동일한 암호화 컨텍스트가 필요합니다. 이러한 값을 사용하여 [AWS CloudTrail 로그](https://docs.aws.amazon.com/kms/latest/developerguide/monitoring-overview.html)에서에 대한 호출을 식별할 수 AWS KMS 있습니다.
   + amzn-ddb-env-alg – 암호화 알고리즘, 기본값은 AES/256
   + amzn-ddb-sig-alg – 서명 알고리즘, 기본값은 HmacSHA256/256
   + (선택 사항) aws-kms-table – *테이블 이름*
   + (선택 사항) *파티션 키 이름* – *파티션 키 값*(이진 값은 Base64로 인코딩됨)
   + (선택 사항) *정렬 키 이름* – *정렬 키 값*(이진 값은 Base64로 인코딩됨)

   Direct KMS Provider는 항목의 DynamoDB AWS KMS 암호화 컨텍스트에서 암호화 컨텍스트 값을 가져옵니다. [DynamoDB ](concepts.md#encryption-context) DynamoDB 암호화 컨텍스트에 테이블 이름과 같은 값이 포함되지 않은 경우 해당 이름-값 페어는 AWS KMS 암호화 컨텍스트에서 생략됩니다.

1. Direct KMS Provider는 데이터 키에서 대칭 암호화 키 및 서명 키를 추출합니다. 기본적으로 [Secure Hash Algorithm(SHA) 256](https://en.wikipedia.org/wiki/SHA-2) 및 [RFC5869 HMAC 기반 키 추출 함수](https://tools.ietf.org/html/rfc5869)를 사용하여 256비트 AES 대칭 암호화 키 및 256비트 HMAC-SHA-256 서명 키를 추출합니다.

1. Direct KMS Provider는 출력을 항목 암호화 도구로 반환합니다.

1. 항목 암호화기는 암호화 키를 사용하여 지정된 속성을 암호화하고 서명 키를 사용하여 실제 자료 설명에 지정된 알고리즘을 사용하여 서명합니다. 가능한 한 빨리 메모리에서 일반 텍스트 키를 제거합니다.

### 복호화 자료 가져오기
<a name="direct-kms-get-decryption-materials"></a>

이 단원에서는 [항목 암호화 도구](DDBEC-legacy-concepts.md#item-encryptor)에서 복호화 자료 요청 수신 시 Direct KMS Provider의 입력, 출력 및 처리를 자세히 설명합니다.

**입력**(애플리케이션에서)
+ 의 키 ID입니다 AWS KMS key.

  키 ID의 값은 AWS KMS key의 키 ID, 키 ARN, 별칭 이름 또는 별칭 ARN일 수 있습니다. 리전과 같이 키 ID에 포함되지 않은 모든 값은 [AWS 명명된 프로필](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles)에서 사용할 수 있어야 합니다. 키 ARN은 에 AWS KMS 서 필요로 하는 모든 값을 제공합니다.

**입력**(항목 암호화 도구에서)
+ 자료 설명 속성의 내용을 포함하는 [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)의 복사본입니다.

**출력**(항목 암호화 도구로)
+ 암호화 키(일반 텍스트)
+ 서명 키

**처리**

1. Direct KMS Provider는 암호화된 항목의 자료 설명 속성에서 암호화된 데이터 키를 가져옵니다.

1. 지정된를 사용하여 암호화된 데이터 키를 AWS KMS key [해독](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) AWS KMS 하도록 요청합니다. 이 작업은 일반 텍스트 키를 반환합니다.

   이 요청은 데이터 키를 생성 및 암호화하는 데 사용된 것과 동일한 [AWS KMS 암호화 컨텍스트](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)를 사용해야 합니다.
   + aws-kms-table – *테이블 이름*
   + *파티션 키 이름* – *파티션 키 값*(이진 값은 Base64로 인코딩됨)
   + (선택 사항) *정렬 키 이름* – *정렬 키 값*(이진 값은 Base64로 인코딩됨)
   + amzn-ddb-env-alg – 암호화 알고리즘, 기본값은 AES/256
   + amzn-ddb-sig-alg – 서명 알고리즘, 기본값은 HmacSHA256/256

1. Direct KMS Provider는 [Secure Hash Algorithm(SHA) 256](https://en.wikipedia.org/wiki/SHA-2) 및 [RFC5869 HMAC 기반 키 파생 기능](https://tools.ietf.org/html/rfc5869)을 사용하여 데이터 키에서 256비트 AES 대칭 암호화 키와 256비트 HMAC-SHA-256 서명 키를 파생합니다.

1. Direct KMS Provider는 출력을 항목 암호화 도구로 반환합니다.

1. 항목 암호화기는 서명 키를 사용하여 항목을 확인합니다. 성공하면 대칭 암호화 키를 사용하여 암호화된 속성 값을 복호화합니다. 이러한 작업은 실제 자료 설명에 지정된 암호화 및 서명 알고리즘을 사용합니다. 항목 암호화 도구는 가능한 한 빨리 메모리에서 일반 텍스트 키를 제거합니다.

# Wrapped Materials Provider
<a name="wrapped-provider"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

*래핑된 자료 공급자*(래핑된 CMP)를 사용하면 DynamoDB Encryption Client를 통해 모든 소스의 래핑 및 서명 키를 사용할 수 있습니다. 래핑된 CMP는 AWS 서비스에 종속되지 않습니다. 그러나 항목을 확인하고 복호화하기 위해 올바른 키를 제공하는 것을 포함하여 클라이언트 외부에서 래핑 및 서명 키를 생성하고 관리해야 합니다.

래핑된 CMP는 각 항목에 대해 고유한 항목 암호화 키를 생성합니다. 사용자가 제공하는 래핑 키와 항목 암호화 키를 래핑하여 래핑된 항목 암호화 키를 항목의 [자료 설명 속성](DDBEC-legacy-concepts.md#legacy-material-description)에 저장합니다. 래핑 및 서명 키를 제공하므로 래핑 및 서명 키가 생성되는 방법과 해당 키가 각 항목에 고유한지 또는 재사용되는지 여부를 결정합니다.

래핑된 CMP는 안전한 구현이며 암호화 자료를 관리할 수 있는 애플리케이션에 적합한 선택입니다.

래핑된 CMP는 DynamoDB Encryption Client가 지원하는 여러 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP) 중 하나입니다. 기타 CMP에 대한 자세한 내용은 [암호화 자료 공급자](crypto-materials-providers.md) 섹션을 참조하세요.

**예제 코드는 다음을 참조하십시오.**
+ Java: [AsymmetricEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AsymmetricEncryptedItem.java)
+ Python: [wrapped-rsa-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/wrapped_rsa_encrypted_table.py), [wrapped-symmetric-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/wrapped_symmetric_encrypted_table.py)

**Topics**
+ [사용 방법](#wrapped-cmp-how-to-use)
+ [작동 방식](#wrapped-cmp-how-it-works)

## 사용 방법
<a name="wrapped-cmp-how-to-use"></a>

래핑된 CMP를 생성하려면 래핑 키(암호화에 필요), 래핑 해제 키(복호화에 필요) 및 서명 키를 지정합니다. 항목을 암호화하고 복호화할 때 키를 제공해야 합니다.

래핑, 래핑 해제 및 서명 키는 대칭 키 또는 비대칭 키 페어일 수 있습니다.

------
#### [ Java ]

```
// This example uses asymmetric wrapping and signing key pairs
final KeyPair wrappingKeys = ...
final KeyPair signingKeys = ...

final WrappedMaterialsProvider cmp = 
    new WrappedMaterialsProvider(wrappingKeys.getPublic(),
                                 wrappingKeys.getPrivate(),
                                 signingKeys);
```

------
#### [ Python ]

```
# This example uses symmetric wrapping and signing keys
wrapping_key = ...
signing_key  = ...

wrapped_cmp = WrappedCryptographicMaterialsProvider(
    wrapping_key=wrapping_key,
    unwrapping_key=wrapping_key,
    signing_key=signing_key
)
```

------

## 작동 방식
<a name="wrapped-cmp-how-it-works"></a>

래핑된 CMP는 모든 항목에 대해 새 항목 암호화 키를 생성합니다. 다음 다이어그램과 같이 사용자가 제공하는 래핑, 래핑 해제 및 서명 키를 사용합니다.

![\[DynamoDB Encryption Client에서 래핑된 자료 공급자의 입력, 처리 및 출력\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/wrappedCMP.png)


### 암호화 자료 가져오기
<a name="wrapped-cmp-get-encryption-materials"></a>

이 단원에서는 암호화 자료 요청 수신 시 래핑된 자료 공급자(래핑된 CMP)의 입력, 출력 및 처리에 대해 자세히 설명합니다.

**입력**(애플리케이션에서)
+ 래핑 키: [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)(AES) 대칭 키 또는 [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) 퍼블릭 키. 속성 값이 암호화된 경우 필수입니다. 그렇지 않으면 선택 사항이며 무시됩니다.
+ 래핑 해제 키: 선택 사항이며 무시됩니다.
+ 서명 키

**입력**(항목 암호화 도구에서)
+ [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)

**출력**(항목 암호화 도구로):
+ 일반 텍스트 항목 암호화 키
+ 서명 키(변경되지 않음)
+ [실제 자료 설명](DDBEC-legacy-concepts.md#legacy-material-description): 이러한 값은 클라이언트가 항목에 추가하는 [자료 설명 속성](DDBEC-legacy-concepts.md#legacy-material-description)에 저장됩니다.
  + `amzn-ddb-env-key`: Base64로 인코딩되고 래핑된 항목 암호화 키
  + `amzn-ddb-env-alg`: 항목을 암호화하는 데 사용되는 암호화 알고리즘입니다. 기본값은 AES-256-CBC입니다.
  + `amzn-ddb-wrap-alg`: 래핑된 CMP가 항목 암호화 키를 래핑하는 데 사용한 래핑 알고리즘입니다. 래핑 키가 AES 키인 경우 [RFC 3394](https://tools.ietf.org/html/rfc3394.html)에 정의된 대로 패딩되지 않은 `AES-Keywrap`를 사용하여 키가 래핑됩니다. 래핑 키가 RSA 키인 경우 MGF1 패딩이 포함된 RSA OAEP를 사용하여 키가 암호화됩니다.

**처리**

항목을 암호화할 때 래핑 키와 서명 키를 전달합니다. 래핑 해제 키는 선택 사항이며 무시됩니다.

1. 래핑된 CMP는 테이블 항목에 대한 고유한 대칭 항목 암호화 키를 생성합니다.

1. 항목 암호화 키를 래핑하기 위해 지정한 래핑 키를 사용합니다. 그런 다음 가능한 한 빨리 메모리에서 제거합니다.

1. Wrapped CMP는 일반 텍스트 항목 암호화 키, 제공한 서명 키, 그리고 래핑된 항목 암호화 키와 암호화 및 래핑 알고리즘을 포함하는 [실제 자료 설명](DDBEC-legacy-concepts.md#legacy-material-description)을 반환합니다.

1. 항목 암호화 도구는 일반 텍스트 암호화 키를 사용하여 항목을 암호화합니다. 항목에 서명하기 위해 제공한 서명 키를 사용합니다. 그런 다음 가능한 한 빨리 메모리에서 일반 텍스트 키를 제거합니다. 래핑된 암호화 키(`amzn-ddb-env-key`)를 포함하여 실제 자료 설명의 필드를 항목의 자료 설명 속성에 복사합니다.

### 복호화 자료 가져오기
<a name="wrapped-cmp-get-decryption-materials"></a>

이 단원에서는 복호화 자료 요청 수신 시 래핑된 자료 공급자(래핑된 CMP)의 입력, 출력 및 처리에 대해 자세히 설명합니다.

**입력**(애플리케이션에서)
+ 래핑 키: 선택 사항이며 무시됩니다.
+ 언래핑 키: 암호화하는 데 사용되는 RSA 퍼블릭 키에 해당하는 동일한 [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)(AES) 대칭 키 또는 [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) 프라이빗 키입니다. 속성 값이 암호화된 경우 필수입니다. 그렇지 않으면 선택 사항이며 무시됩니다.
+ 서명 키

**입력**(항목 암호화 도구에서)
+ 자료 설명 속성의 내용을 포함하는 [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)의 복사본입니다.

**출력**(항목 암호화 도구로)
+ 일반 텍스트 항목 암호화 키
+ 서명 키(변경되지 않음)

**처리**

항목의 암호를 복호화할 때 래핑 해제 키와 서명 키를 전달합니다. 래핑 키는 선택 사항이며 무시됩니다.

1. 래핑된 CMP는 항목의 자료 설명 속성에서 래핑된 항목 암호화 키를 가져옵니다.

1. 래핑 해제 키와 알고리즘을 사용하여 항목 암호화 키를 래핑 해제합니다.

1. 일반 텍스트 항목 암호화 키, 서명 키, 암호화 및 서명 알고리즘을 항목 암호화 도구에 반환합니다.

1. 항목 암호화기는 서명 키를 사용하여 항목을 확인합니다. 성공하면 항목 암호화 키를 사용하여 항목의 암호를 복호화합니다. 그런 다음 가능한 한 빨리 메모리에서 일반 텍스트 키를 제거합니다.

# Most Recent Provider
<a name="most-recent-provider"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

*Most Recent Provider*는 [공급자 스토어](DDBEC-legacy-concepts.md#provider-store)와 함께 작동하도록 설계된 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)입니다. 공급자 스토어에서 CMP를 가져오고 CMP에서 반환한 암호화 자료를 가져옵니다. 일반적으로 각 CMP를 사용하여 암호화 자료에 대한 여러 요청을 충족합니다. 하지만 공급자 스토어의 기능을 사용하여 자료가 재사용되는 범위를 제어하고 CMP 교체 빈도를 결정할 수 있으며, Most Recent Provider를 변경하지 않고 사용하는 CMP 유형을 변경할 수도 있습니다.

**참고**  
Most Recent Provider의 `MostRecentProvider` 기호와 연관된 코드는 프로세스 수명 동안 암호화 자료를 메모리에 저장할 수 있습니다. 호출자가 더 이상 사용 권한이 없는 키를 사용하도록 허용할 수도 있습니다.  
`MostRecentProvider` 기호는 지원되는 이전 버전의 DynamoDB Encryption Client에서 더 이상 사용되지 않으며 버전 2.0.0에서 제거되었습니다. `CachingMostRecentProvider` 기호로 대체됩니다. 자세한 내용은 [Most Recent Provider 업데이트](#mrp-versions)을 참조하세요.

Most Recent Provider는 공급자 스토어 및 관련 암호화 소스에 대한 호출을 최소화해야 하는 애플리케이션과, 보안 요구 사항을 위반하지 않으면서 일부 암호화 자료를 재사용할 수 있는 애플리케이션에 적합합니다. 예를 들어 항목을 암호화하거나 해독할 AWS KMS 때마다를 호출하지 않고 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS)의 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)에서 암호화 자료를 보호할 수 있습니다.

선택하는 공급자 스토어는 Most Recent Provider에서 사용하는 CMP 유형과 새 CMP를 가져오는 빈도를 결정합니다. 사용자가 설계한 사용자 정의 공급자 저장소를 포함하여 Most Recent Provider와 호환되는 모든 공급자 스토어를 사용할 수 있습니다.

DynamoDB Encryption Client에는 [래핑된 자료 공급자](wrapped-provider.md)(래핑된 CMP)를 생성하고 반환하는 MetaStore가 포함되어 있습니다.** MetaStore는 생성한 래핑된 CMP의 여러 버전을 내부 DynamoDB 테이블에 저장하고 DynamoDB Encryption Client의 내부 인스턴스를 통한 클라이언트측 암호화로 이를 보호합니다.

모든 유형의 내부 CMP를 사용하여 테이블의 자료를 보호하도록 MetaStore를 구성할 수 있습니다. 여기에는 로 보호되는 암호화 자료를 생성하는 [다이렉트 KMS 공급자](direct-kms-provider.md) AWS KMS key, 사용자가 제공하는 래핑 및 서명 키를 사용하는 래핑된 CMP 또는 사용자가 설계하는 호환되는 사용자 지정 CMP가 포함됩니다.

**예제 코드는 다음을 참조하십시오.**
+ Java: [MostRecentEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/MostRecentEncryptedItem.java)
+ Python: [most\$1recent\$1provider\$1encrypted\$1table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/most_recent_provider_encrypted_table.py)

**Topics**
+ [사용 방법](#mrp-how-to-use-it)
+ [작동 방식](#mrp-how-it-works)
+ [Most Recent Provider 업데이트](#mrp-versions)

## 사용 방법
<a name="mrp-how-to-use-it"></a>

Most Recent Provider를 생성하려면 공급자 저장소를 생성 및 구성한 다음 공급자 스토어를 사용하는 Most Recent Provider를 생성해야 합니다.

다음 예제에서는 MetaStore를 사용하고 [Direct KMS Provider](direct-kms-provider.md)의 암호화 자료로 내부 DynamoDB 테이블의 버전을 보호하는 Most Recent Provider를 생성하는 방법을 보여줍니다. 이 예제에서는 [`CachingMostRecentProvider`](#mrp-versions) 기호를 사용합니다.

각 Most Recent Provider에는 MetaStore 테이블에서 CMP를 식별하는 이름, [time-to-live](#most-recent-provider-ttl)(TTL) 설정, 캐시가 보유할 수 있는 항목 수를 결정하는 캐시 크기 설정이 있습니다. 이 예제에서는 캐시 크기를 항목 1,000개와 TTL 한 개를 60초로 설정합니다.

------
#### [ Java ]

```
// Set the name for MetaStore's internal table
final String keyTableName = 'metaStoreTable'

// Set the Region and AWS KMS key
final String region = 'us-west-2'
final String keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

// Set the TTL and cache size
final long ttlInMillis = 60000;
final long cacheSize = 1000;

// Name that identifies the MetaStore's CMPs in the provider store
final String materialName = 'testMRP'

// Create an internal DynamoDB client for the MetaStore
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.standard().withRegion(region).build();

// Create an internal Direct KMS Provider for the MetaStore
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider kmsProv = new DirectKmsMaterialProvider(kms, keyArn);

// Create an item encryptor for the MetaStore,
// including the Direct KMS Provider
final DynamoDBEncryptor keyEncryptor = DynamoDBEncryptor.getInstance(kmsProv);

// Create the MetaStore
final MetaStore metaStore = new MetaStore(ddb, keyTableName, keyEncryptor);

//Create the Most Recent Provider
final CachingMostRecentProvider cmp = new CachingMostRecentProvider(metaStore, materialName, ttlInMillis, cacheSize);
```

------
#### [ Python ]

```
# Designate an AWS KMS key
kms_key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

# Set the name for MetaStore's internal table
meta_table_name = 'metaStoreTable'

# Name that identifies the MetaStore's CMPs in the provider store
material_name = 'testMRP'

# Create an internal DynamoDB table resource for the MetaStore
meta_table = boto3.resource('dynamodb').Table(meta_table_name)

# Create an internal Direct KMS Provider for the MetaStore
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
    
# Create the MetaStore with the Direct KMS Provider
meta_store = MetaStore(
    table=meta_table,
    materials_provider=kms_cmp
)

# Create a Most Recent Provider using the MetaStore
#    Sets the TTL (in seconds) and cache size (# entries)
most_recent_cmp = MostRecentProvider(
    provider_store=meta_store,
    material_name=material_name,
    version_ttl=60.0,
    cache_size=1000
)
```

------

## 작동 방식
<a name="mrp-how-it-works"></a>

Most Recent Provider는 공급자 스토어에서 CMP를 가져옵니다. 그런 다음 CMP를 사용하여 항목 암호화 도구에 반환되는 암호화 자료를 생성합니다.

### 최신 제공자 정보
<a name="about-mrp"></a>

Most Recent Provider는 [공급자 스토어](DDBEC-legacy-concepts.md#provider-store)에서 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)를 가져옵니다. 그런 다음 CMP를 사용하여 반환되는 암호화 자료를 생성합니다. 각 Most Recent Provider는 하나의 공급자 스토어와 연결되어 있지만 공급자 스토어는 여러 호스트에 걸쳐 여러 공급자에게 CMP를 제공할 수 있습니다.

Most Recent Provider는 모든 공급자 스토어의 호환되는 CMP와 함께 사용할 수 있습니다. CMP에서 암호화 또는 복호화 자료를 요청하고 출력을 항목 암호화 도구로 반환합니다. 어떠한 암호화 작업도 수행하지 않습니다.

Most Recent Provider는 공급자 스토어에서 CMP를 요청하기 위해 관련 자료 이름과 사용할 기존 CMP의 버전을 제공합니다. 암호화 자료의 경우 Most Recent Provider는 항상 최대("최신") 버전을 요청합니다. 복호화 자료의 경우 다음 다이어그램과 같이 암호화 자료를 생성하는 데 사용된 CMP 버전을 요청합니다.

![\[Most Recent Provider\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/most-recent-provider-1.png)


Most Recent Provider는 공급자 스토어에서 반환하는 CMP의 버전을 메모리의 로컬 Least Recently Used(LRU) 캐시에 저장합니다. 이 캐시에서는 Most Recent Provider가 모든 항목에 대해 공급자 스토어를 호출하지 않고 필요한 CMP를 가져올 수 있습니다. 요청 시 캐시를 지울 수 있습니다.

Most Recent Provider는 애플리케이션의 특성에 따라 조정할 수 있는 구성 가능한 [time-to-live 값](#most-recent-provider-ttl)을 사용합니다.

### MetaStore 정보
<a name="about-metastore"></a>

호환되는 사용자 지정 공급자 스토어를 비롯하여 모든 공급자 스토어와 함께 Most Recent Provider를 사용할 수 있습니다. DynamoDB Encryption Client에는 구성하고 사용자 지정할 수 있는 보안 구현인 MetaStore가 포함되어 있습니다.

MetaStore는 래핑된 CMP에 필요한 래핑 키, 언래핑 키, 서명 키로 구성된 [래핑된 CMP](wrapped-provider.md)를 생성하고 반환하는 [공급자 스토어](DDBEC-legacy-concepts.md#provider-store)입니다.** 래핑된 CMP는 항상 모든 항목에 대해 고유한 항목 암호화 키를 생성하므로 MetaStore는 Most Recent Provider를 위한 안전한 옵션입니다. 항목 암호화 키와 서명 키를 보호하는 래핑 키만 재사용됩니다.

다음 다이어그램은 MetaStore의 구성 요소, 그리고 이러한 구성 요소가 Most Recent Provider와 어떻게 상호 작용하는지를 보여줍니다.

![\[MetaStore\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/most-recent-provider-2.png)


MetaStore는 래핑된 CMP를 생성한 다음 이를 암호화된 형식으로 내부 DynamoDB 테이블에 저장합니다. 파티션 키는 Most Recent Provider 자료의 이름입니다. 정렬 키의 버전 번호입니다. 테이블의 자료는 항목 암호화 도구 및 내부 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)를 포함한 내부 DynamoDB Encryption Client에 의해 보호됩니다.

[Direct KMS Provider](wrapped-provider.md), Wrapped CMP(사용자가 제공하는 암호화 자료 포함) 또는 호환되는 사용자 지정 CMP 등 MetaStore에서 원하는 내부 CMP 유형을 사용할 수 있습니다. MetaStore의 내부 CMP가 Direct KMS Provider인 경우 재사용 가능한 래핑 및 서명 키는 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS)의 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)에 따라 보호됩니다. MetaStore는 내부 테이블에 새 CMP 버전을 추가하거나 내부 테이블에서 CMP 버전을 가져올 AWS KMS 때마다를 호출합니다.

### time-to-live 값 설정
<a name="most-recent-provider-ttl"></a>

생성한 각 Most Recent Provider에 대해 time-to-live(TTL) 값을 설정할 수 있습니다. 일반적으로 애플리케이션에 실용적인 가장 낮은 TTL 값을 사용합니다.

Most Recent Provider에 대한 `CachingMostRecentProvider` 기호에서 TTL 값의 사용이 변경되었습니다.

**참고**  
Most Recent Provider에 대한 `MostRecentProvider` 기호는 지원되는 이전 버전의 DynamoDB Encryption Client에서 더 이상 사용되지 않으며 버전 2.0.0에서 제거됩니다. `CachingMostRecentProvider` 기호로 대체됩니다. 가능한 한 빨리 코드를 업데이트하는 것이 좋습니다. 자세한 내용은 [Most Recent Provider 업데이트](#mrp-versions)을 참조하세요.

**`CachingMostRecentProvider`**  
`CachingMostRecentProvider`는 TTL 값은 두 가지 다른 방식으로 사용됩니다.  
+ TTL은 Most Recent Provider가 공급자 스토어에서 CMP의 새 버전을 확인하는 빈도를 결정합니다. 새 버전을 사용할 수 있는 경우 Most Recent Provider는 CMP를 교체하고 암호화 자료를 새로 고칩니다. 그렇지 않으면 현재 CMP 및 암호화 자료를 계속 사용합니다.
+ TTL은 캐시의 CMP를 사용할 수 있는 기간을 결정합니다. Most Recent Provider는 암호화를 위해 캐시된 CMP를 사용하기 전에 캐시에 있는 시간을 평가합니다. CMP 캐시 시간이 TTL을 초과하면 CMP가 캐시에서 제거되고 Most Recent Provider는 해당 공급자 저장소에서 새로운 최신 버전의 CMP를 가져옵니다.

**`MostRecentProvider`**  
`MostRecentProvider`에서 TTL은 Most Recent Provider가 공급자 스토어에서 CMP의 새 버전을 확인하는 빈도를 결정합니다. 새 버전을 사용할 수 있는 경우 Most Recent Provider는 CMP를 교체하고 암호화 자료를 새로 고칩니다. 그렇지 않으면 현재 CMP 및 암호화 자료를 계속 사용합니다.

TTL은 새 CMP 버전이 생성되는 빈도를 결정하지 않습니다. [암호화 자료를 교체하여](#most-recent-provider-rotate) 새로운 CMP 버전을 생성합니다.

이상적인 TTL 값은 애플리케이션과 해당 지연 시간 및 가용성 목표에 따라 다릅니다. TTL이 낮을수록 암호화 자료가 메모리에 저장되는 시간이 줄어들어 보안 프로필이 향상됩니다. 또한 TTL이 낮을수록 중요한 정보가 더 자주 새로 고쳐집니다. 예를 들어 내부 CMP가 [Direct KMS Provider](direct-kms-provider.md)인 경우, 발신자가 여전히 AWS KMS key를 사용할 권한이 있는지 더 자주 확인합니다.

그러나 TTL이 너무 짧은 경우 공급자 스토어를 자주 호출하면 비용이 증가하고 공급자 스토어가 애플리케이션 및 서비스 계정을 공유하는 기타 애플리케이션의 요청을 제한할 수 있습니다. 암호화 자료를 회전하는 속도에 따라 TTL을 조정하면 이점을 얻을 수도 있습니다.

테스트하는 동안 애플리케이션과 보안 및 성능 표준에 적합한 구성을 찾을 때까지 다양한 작업 부하에 따라 TTL과 캐시 크기를 다양하게 변경합니다.

### 암호화 자료 교체
<a name="most-recent-provider-rotate"></a>

Most Recent Provider는 암호화 자료가 필요할 때 항상 자신이 알고 있는 CMP의 최신 버전을 사용합니다. 최신 버전을 확인하는 빈도는 가장 Most Recent Provider를 구성할 때 설정한 [time-to-live](#most-recent-provider-ttl)(TTL) 값에 따라 결정됩니다.

TTL이 만료되면 Most Recent Provider는 공급자 저장소에서 최신 버전의 CMP를 확인합니다. 사용 가능한 CMP가 있는 경우 Most Recent Provider는 이를 가져와 캐시의 CMP를 교체합니다. 공급자 스토어에 최신 버전이 있다는 것을 발견할 때까지 이 CMP와 해당 암호화 자료를 사용합니다.

공급자 스토어에 Most Recent Provider로 새 CMP 버전을 만들도록 알리려면 Most Recent Provider의 자료 이름을 사용하여 공급자 스토어의 새 공급자 만들기 작업을 호출합니다. 공급자 스토어는 새 CMP를 생성하고 더 높은 버전 번호로 내부 스토어에 암호화된 복사본을 저장합니다. (CMP도 반환하지만 삭제할 수 있습니다.) 결과적으로 Most Recent Provider는 다음 번에 공급자 스토어에 CMP의 최대 버전 번호를 쿼리할 때 더 큰 새로운 버전 번호를 얻고 이를 저장소에 대한 후속 요청에 사용하여 CMP의 새 버전이 생성되었는지 확인합니다.

시간, 처리된 항목이나 속성의 수, 애플리케이션에 적합한 기타 지표를 기준으로 새 공급자 생성 호출을 예약할 수 있습니다.

### 암호화 자료 가져오기
<a name="most-recent-provider-encrypt"></a>

Most Recent Provider는 이 다이어그램에 표시된 다음과 같은 프로세스를 통해 항목 암호화 도구로 반환되는 암호화 자료를 가져옵니다. 출력은 공급자 스토어가 반환하는 CMP 유형에 따라 달라집니다. Most Recent Provider는 DynamoDB Encryption Client에 포함된 MetaStore를 포함하여 호환되는 모든 공급자 스토어를 사용할 수 있습니다.

![\[DynamoDB Encryption Client에서 Most Recent Provider의 입력, 처리 및 출력\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/most-recent-provider-provider-store.png)


[`CachingMostRecentProvider` 기호](#mrp-versions)를 사용하여 Most Recent Provider를 생성할 때 공급자 스토어, Most Recent Provider의 이름 및 [time-to-live](#most-recent-provider-ttl)(TTL) 값을 지정합니다. 캐시에 존재할 수 있는 암호화 자료의 최대 수를 결정하는 캐시 크기를 선택적으로 지정할 수도 있습니다.

이 항목이 Most Recent Provider에 암호화 자료를 요청하면 Most Recent Provider는 캐시에서 CMP의 최신 버전을 검색하는 것부터 시작합니다.
+ 캐시에서 최신 버전의 CMP를 찾았고 CMP가 TTL 값을 초과하지 않은 경우 Most Recent Provider는 CMP를 사용하여 암호화 자료를 생성합니다. 그런 다음 암호화 자료를 항목 암호화 도구에 반환합니다. 이 작업에는 공급자 스토어를 호출할 필요가 없습니다.
+ 최신 버전의 CMP가 캐시에 없거나 캐시에 있지만 TTL 값을 초과한 경우 Most Recent Provider는 공급자 스토어에서 CMP를 요청합니다. 요청에는 Most Recent Provider 자료 이름과 알고 있는 최대 버전 번호가 포함됩니다.

  1. 공급자 스토어는 영구 스토리지에서 CMP를 반환합니다. 공급자 스토어가 MetaStore인 경우 가장 최근 공급자 자료 이름을 파티션 키로 사용하고, 버전 번호를 정렬 키로 사용하여 내부 DynamoDB 테이블에서 암호화되고 래핑된 CMP를 가져옵니다. MetaStore는 내부 항목 암호화 도구와 내부 CMP를 사용하여 래핑된 CMP를 복호화합니다. 그런 다음 일반 텍스트 CMP를 Most Recent Provider에 반환합니다. 내부 CMP가 [Direct KMS Provider](direct-kms-provider.md)이면 이 단계에는 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS)에 대한 호출이 포함됩니다.

  1. CMP 는 `amzn-ddb-meta-id` 필드를 [실제 자료 설명](DDBEC-legacy-concepts.md#legacy-material-description)에 추가합니다. 해당 값은 내부 테이블에 있는 CMP의 자료 이름과 버전입니다. 공급자 스토어는 CMP를 Most Recent Provider에게 반환합니다.

  1. Most Recent Provider는 CMP를 메모리에 캐시합니다.

  1. Most Recent Provider는 CMP를 사용하여 암호화 자료를 생성합니다. 그런 다음 암호화 자료를 항목 암호화 도구에 반환합니다.

### 복호화 자료 가져오기
<a name="most-recent-provider-decrypt"></a>

항목 암호화 도구가 Most Recent Provider에 복호화 자료를 요청하는 경우 Most Recent Provider는 다음 프로세스를 사용하여 이러한 자료를 가져와서 반환합니다.

1. Most Recent Provider는 공급자 스토어에 항목을 암호화하는 데 사용되었던 암호화 자료의 버전 번호를 요청합니다. Most Recent Provider는 항목의 [자료 설명 속성](DDBEC-legacy-concepts.md#legacy-material-description)에서 실제 자료 설명을 전달합니다.

1. 공급자 스토어는 실제 자료 설명의 `amzn-ddb-meta-id` 필드에서 암호화 CMP 버전 번호를 가져와서 Most Recent Provider로 반환합니다.

1. Most Recent Provider는 항목을 암호화 및 서명하는 데 사용되었던 CMP 버전을 캐시에서 검색합니다.
+ CMP의 일치하는 버전이 캐시에 있고 CMP가 [time-to-live(TTL) 값](#most-recent-provider-ttl)을 초과하지 않은 경우 Most Recent Provider는 CMP를 사용하여 복호화 자료를 생성합니다. 그런 다음 복호화 자료를 항목 암호화 도구에 반환합니다. 이 작업에는 공급자 스토어나 다른 CMP에 대한 호출이 필요하지 않습니다.
+ CMP의 일치하는 버전이 캐시에 없거나 캐시된 AWS KMS key 이 TTL 값을 초과한 경우 Most Recent Provider는 공급자 스토어에서 CMP를 요청합니다. 요청에 자료 이름과 암호화 CMP 버전 번호를 보냅니다.

  1. 공급자 스토어는 Most Recent Provider 이름을 파티션 키로 사용하고 버전 번호를 정렬 키로 사용하여 CMP에 대한 영구 스토리지를 검색합니다.
     + 이름과 버전 번호가 영구 스토리지에 없으면 공급자 스토어에서 예외가 발생합니다. 공급자 스토어를 사용하여 CMP를 생성한 경우 의도적으로 삭제하지 않는 한 CMP는 영구 스토리지에 저장되어야 합니다.
     + CMP와 해당 이름 및 버전 번호가 공급자 스토어의 영구 스토리지 안에 있으면 공급자 스토어가 지정된 CMP를 Most Recent Provider로 반환합니다.

       공급자 스토어가 MetaStore인 경우 DynamoDB 테이블에서 암호화된 CMP를 가져옵니다. 그런 다음 CMP를 Most Recent Provider로 반환하기 전에 내부 CMP의 암호화 자료를 사용하여 암호화된 CMP를 복호화합니다. 내부 CMP가 [Direct KMS Provider](direct-kms-provider.md)이면 이 단계에는 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS)에 대한 호출이 포함됩니다.

  1. Most Recent Provider는 CMP를 메모리에 캐시합니다.

  1. Most Recent Provider는 CMP를 사용하여 복호화 자료를 생성합니다. 그런 다음 복호화 자료를 항목 암호화 도구에 반환합니다.

## Most Recent Provider 업데이트
<a name="mrp-versions"></a>

Most Recent Provider의 기호가 `MostRecentProvider`에서 `CachingMostRecentProvider`로 변경되었습니다.

**참고**  
Most Recent Provider를 나타내는 `MostRecentProvider` 기호는 Java용 DynamoDB Encryption Client 버전 1.15 및 Python용 DynamoDB Encryption Client 버전 1.3에서 더 이상 사용되지 않으며 두 언어 구현 모두의 DynamoDB Encryption Client 버전 2.0.0에서 제거됩니다. 그 대신 `CachingMostRecentProvider`을 사용합니다.

`CachingMostRecentProvider`에서는 다음 변경 사항을 구현합니다.
+ `CachingMostRecentProvider`는 메모리 내 시간이 구성된 [time-to-live(TTL) 값](#most-recent-provider-ttl)을 초과하는 경우 메모리에서 암호화 자료를 주기적으로 제거합니다.

  `MostRecentProvider`는 프로세스 수명 동안 암호화 자료를 메모리에 저장할 수 있습니다. 결과적으로 Most Recent Provider는 인증 변경 사항을 인식하지 못할 수도 있습니다. 호출자의 암호화 키 사용 권한이 취소된 후 암호화 키를 사용할 수 있습니다.

  이 새 버전으로 업데이트할 수 없는 경우 주기적으로 캐시에서 `clear()` 방법를 호출하면 비슷한 효과를 얻을 수 있습니다. 이 방법를 사용하면 캐시 콘텐츠를 수동으로 플러시하고 Most Recent Provider가 새 CMP 및 새 암호화 자료를 요청해야 합니다.
+ 또한 `CachingMostRecentProvider`에는 캐시를 더 효과적으로 제어할 수 있는 캐시 크기 설정도 포함되어 있습니다.

`CachingMostRecentProvider`로 업데이트하려면 코드에서 기호 이름을 변경해야 합니다. 다른 모든 측면에서 `CachingMostRecentProvider`는 `MostRecentProvider`와 완전히 역호환됩니다. 테이블 항목을 다시 암호화할 필요가 없습니다.

그러나 `CachingMostRecentProvider`는 기본 키 인프라에 대한 더 많은 호출을 생성합니다. 각 time-to-live(TTL) 간격마다 공급자 스토어를 한 번 이상 호출합니다. 활성 CMP가 많은 애플리케이션(빈번한 교체로 인해) 또는 대규모 플릿이 있는 애플리케이션은 이러한 변화에 민감할 가능성이 높습니다.

업데이트된 코드를 릴리스하기 전에 철저히 테스트하여 더 빈번한 호출로 인해 애플리케이션이 손상되거나 AWS Key Management Service (AWS KMS) 또는 Amazon DynamoDB와 같이 공급자가 의존하는 서비스에 의한 제한이 발생하지 않는지 확인합니다. 성능 문제를 완화하려면 관찰한 성능 특성에 따라 캐시 크기와 `CachingMostRecentProvider`의 수명을 조정합니다. 자세한 지침은 [time-to-live 값 설정](#most-recent-provider-ttl)을 참조하세요.

# Static Materials Provider
<a name="static-provider"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

*Static Materials Provider*(정적 CMP)는 테스트, 개념 증명 데모 및 레거시 호환성을 위한 매우 간단한 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)입니다.

Static CMP를 사용하여 테이블 항목을 암호화하려면 [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)(AES) 대칭 암호화 키 및 서명 키 또는 키 페어를 제공합니다. 암호화된 항목을 복호화하려면 동일한 키를 제공해야 합니다. 정적 CMP는 어떠한 암호화 작업도 수행하지 않습니다. 대신, 사용자가 제공한 암호화 키를 항목 암호화 도구에 변경되지 않은 상태로 전달합니다. 항목 암호화 도구는 암호화 키 바로 아래에 있는 항목을 암호화합니다. 그런 다음 서명 키를 직접 사용하여 서명합니다.

정적 CMP는 고유한 암호화 자료를 생성하지 않기 때문에 처리하는 모든 테이블 항목은 동일한 암호화 키로 암호화되고 동일한 서명 키로 서명됩니다. 동일한 키를 사용하여 수많은 항목의 속성 값을 암호화하거나 동일한 키 또는 키 페어를 사용하여 모든 항목에 서명하면 키의 암호화 제한을 초과할 위험이 있습니다.

**참고**  
Java 라이브러리의 [Asymmetric Static Provider](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/AsymmetricStaticProvider.html)는 Static Provider가 아닙니다. 단순히 [Wrapped CMP](wrapped-provider.md)에 대한 대체 생성자를 제공할 뿐입니다. 프로덕션 환경에서는 안전하지만 가능하면 래핑된 CMP를 직접 사용해야 합니다.

정적 CMP는 DynamoDB Encryption Client가 지원하는 여러 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP) 중 하나입니다. 기타 CMP에 대한 자세한 내용은 [암호화 자료 공급자](crypto-materials-providers.md) 섹션을 참조하세요.

**예제 코드는 다음을 참조하십시오.**
+ Java: [SymmetricEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/SymmetricEncryptedItem.java)

**Topics**
+ [사용 방법](#static-cmp-how-to-use)
+ [작동 방식](#static-cmp-how-it-works)

## 사용 방법
<a name="static-cmp-how-to-use"></a>

정적 공급자를 생성하려면 암호화 키 또는 키 페어와 서명 키 또는 키 페어를 제공합니다. 테이블 항목을 암호화하고 복호화하려면 키 자료를 제공해야 합니다.

------
#### [ Java ]

```
// To encrypt
SecretKey cek = ...;        // Encryption key
SecretKey macKey =  ...;    // Signing key
EncryptionMaterialsProvider provider = new SymmetricStaticProvider(cek, macKey);

// To decrypt
SecretKey cek = ...;        // Encryption key
SecretKey macKey =  ...;    // Verification key
EncryptionMaterialsProvider provider = new SymmetricStaticProvider(cek, macKey);
```

------
#### [ Python ]

```
# You can provide encryption materials, decryption materials, or both
encrypt_keys = EncryptionMaterials(
    encryption_key = ...,
    signing_key = ...
)

decrypt_keys = DecryptionMaterials(
    decryption_key = ...,
    verification_key = ...
)

static_cmp = StaticCryptographicMaterialsProvider(
    encryption_materials=encrypt_keys
    decryption_materials=decrypt_keys
)
```

------

## 작동 방식
<a name="static-cmp-how-it-works"></a>

정적 공급자는 항목 암호화 도구에 제공하는 암호화 및 서명 키를 전달합니다(암호화 및 서명 키가 테이블 항목을 암호화 및 서명하는 데 직접 사용된 경우). 각 항목에 대해 다른 키를 제공하지 않는 한 모든 항목에 동일한 키가 사용됩니다.

![\[DynamoDB Encryption Client에서 Static Materials Provider의 입력, 처리 및 출력\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/staticCMP.png)


### 암호화 자료 가져오기
<a name="static-cmp-get-encryption-materials"></a>

이 단원에서는 암호화 자료 요청 수신 시 Static Materials Provider(정적 CMP)의 입력, 출력 및 처리에 대해 자세히 설명합니다.

**입력**(애플리케이션에서)
+ 암호화 키 –[ Advanced Encryption Standard](https://tools.ietf.org/html/rfc3394.html)(AES) 키와 같은 대칭 키여야 합니다.
+ 서명 키 – 대칭 키 또는 비대칭 키 페어일 수 있습니다.

**입력**(항목 암호화 도구에서)
+ [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)

**출력**(항목 암호화 도구로)
+ 암호화 키가 입력으로 전달되었습니다.
+ 서명 키가 입력으로 전달되었습니다.
+ 실제 자료 설명: 변경되지 않은 [요청한 자료 설명](DDBEC-legacy-concepts.md#legacy-material-description)(있는 경우).

### 복호화 자료 가져오기
<a name="static-cmp-get-decryption-materials"></a>

이 단원에서는 복호화 자료 요청 수신 시 Static Materials Provider(정적 CMP)의 입력, 출력 및 처리에 대해 자세히 설명합니다.

암호화 자료를 가져오는 방법과 복호화 자료를 가져오는 방법이 별도로 포함되어 있지만 동작은 동일합니다.

**입력**(애플리케이션에서)
+ 암호화 키 –[ Advanced Encryption Standard](https://tools.ietf.org/html/rfc3394.html)(AES) 키와 같은 대칭 키여야 합니다.
+ 서명 키 – 대칭 키 또는 비대칭 키 페어일 수 있습니다.

**입력**(항목 암호화 도구에서)
+ [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)(사용되지 않음)

**출력**(항목 암호화 도구로)
+ 암호화 키가 입력으로 전달되었습니다.
+ 서명 키가 입력으로 전달되었습니다.

# Amazon DynamoDB Encryption Client에서 사용할 수 있는 프로그래밍 언어
<a name="programming-languages"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

Amazon DynamoDB Encryption Client는 다음 프로그래밍 언어에 사용할 수 있습니다. 언어별 라이브러리는 다양하지만 결과 구현은 상호 운용이 가능합니다. 예를 들어 Java 클라이언트로 항목을 암호화(및 서명)하고 Python 클라이언트로 항목을 복호화할 수 있습니다.

자세한 내용은 해당 주제를 참조하세요.

**Topics**
+ [Java](java.md)
+ [Python](python.md)

# Amazon DynamoDB Encryption Client for Java
<a name="java"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

이 주제에서는 Amazon DynamoDB Encryption Client for Java를 설치하고 사용하는 방법을 설명합니다. DynamoDB Encryption Client를 사용한 프로그래밍에 대한 자세한 내용은 [Java 예제](java-examples.md), GitHub의 aws-dynamodb-encryption-java 리포지토리에 있는 [예제](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples) 및 DynamoDB Encryption Client용 [Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/)을 참조하세요.

**참고**  
Java용 DynamoDB Encryption Client 버전 1.*x*.*x*는 2022년 7월부터 [지원 종료 단계](what-is-database-encryption-sdk.md#support)에 있습니다. 가능한 한 빨리 최신 버전으로 업그레이드하세요.

**Topics**
+ [사전 조건](#java-prerequisites)
+ [설치](#java-installation)
+ [DynamoDB Encryption Client for Java 사용](java-using.md)
+ [Java 예제](java-examples.md)

## 사전 조건
<a name="java-prerequisites"></a>

Amazon DynamoDB Encryption Client for Java를 설치하기 전에 다음 사전 조건이 충족되었는지 확인합니다.

**Java 개발 환경**  
Java 8 이상이 필요합니다. Oracle 웹 사이트에서 [Java SE 다운로드](https://www.oracle.com/java/technologies/downloads/)로 이동한 다음 Java SE Development Kit(JDK)를 다운로드하여 설치합니다.  
Oracle JDK를 사용하는 경우 [Java Cryptography Extension(JCE) Unlimited Strength Jurisdiction Policy File](http://www.oracle.com/java/technologies/javase-jce8-downloads.html)도 다운로드하여 설치해야 합니다.

**AWS SDK for Java**  
애플리케이션이 DynamoDB와 상호 작용 AWS SDK for Java 하지 않더라도 DynamoDB Encryption Client에는의 DynamoDB 모듈이 필요합니다. 전체 SDK를 설치하거나 이 모듈만 설치할 수 있습니다. Maven을 사용하는 경우 `pom.xml` 파일에 `aws-java-sdk-dynamodb`을 추가합니다.  
설치 및 구성에 대한 자세한 내용은 섹션을 AWS SDK for Java참조하세요[AWS SDK for Java](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/getting-started.html).

## 설치
<a name="java-installation"></a>

다음과 같은 방법으로 Amazon DynamoDB Encryption Client for Java를 설치할 수 있습니다.

**직접**  
Amazon DynamoDB Encryption Client for Java를 설치하려면 [aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) GitHub 리포지토리를 복제하거나 다운로드하세요.

**Apache Maven 사용**  
Amazon DynamoDB Encryption Client for Java는 다음 종속성 정의와 함께 [Apache Maven](https://maven.apache.org/)을 통해 사용할 수 있습니다.  

```
<dependency>
  <groupId>com.amazonaws</groupId>
  <artifactId>aws-dynamodb-encryption-java</artifactId>
  <version>version-number</version>
</dependency>
```

SDK를 설치한 후에는 이 가이드의 예제 코드와 GitHub의 [DynamoDB Encryption Client Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/)을 살펴보는 것부터 시작합니다.

# DynamoDB Encryption Client for Java 사용
<a name="java-using"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

이 주제에서는 다른 프로그래밍 언어 구현에서는 찾을 수 없는 Java의 DynamoDB Encryption Client 기능 중 일부를 설명합니다.

DynamoDB Encryption Client를 사용한 프로그래밍에 대한 자세한 내용은 [Java 예제](java-examples.md), GitHub에 대한 `aws-dynamodb-encryption-java repository`의 [예제](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples) 및 DynamoDB Encryption Client용 [Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/)를 참조하세요.



**Topics**
+ [항목 암호화 도구](#attribute-encryptor)
+ [저장 동작 구성](#save-behavior)
+ [Java의 속성 작업](#attribute-actions-java)
+ [테이블 이름 재정의](#override-table-name)

## 항목 암호화 도구: AttributeEncryptor 및 DynamoDBEncryptor
<a name="attribute-encryptor"></a>

Java의 DynamoDB Encryption Client에는 두 개의 [항목 암호화 도구](DDBEC-legacy-concepts.md#item-encryptor), 즉 하위 수준 [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) 및 [AttributeEncryptor](#attribute-encryptor)가 있습니다.

`AttributeEncryptor`는 DynamoDB Encryption Client의에서 [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html)를 사용하는 데 도움이 `DynamoDB Encryptor` 되는 헬퍼 클래스입니다. AWS SDK for Java DynamoDB `DynamoDBMapper`와 함께 `AttributeEncryptor`를 사용하면 사용자가 항목을 저장할 때 항목을 사용자 모르게 암호화하고 서명합니다. 또한 사용자가 항목을 로드할 때 항목을 사용자 모르게 확인하고 복호화합니다.

## 저장 동작 구성
<a name="save-behavior"></a>

`AttributeEncryptor` 및 `DynamoDBMapper`를 사용하여 서명만 있거나 암호화 및 서명된 속성이 있는 테이블 항목을 추가하거나 교체할 수 있습니다. 이러한 작업의 경우 다음 예와 같이 `PUT` 저장 동작을 사용하도록 구성하는 것이 좋습니다. 그렇지 않으면 데이터를 복호화하지 못할 수 있습니다.

```
DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder().withSaveBehavior(SaveBehavior.PUT).build();
DynamoDBMapper mapper = new DynamoDBMapper(ddb, mapperConfig, new AttributeEncryptor(encryptor));
```

테이블 항목에서 모델링된 속성만 업데이트하는 기본 저장 동작을 사용하는 경우 모델링되지 않은 속성은 서명에 포함되지 않으며 테이블 쓰기에 의해 변경되지 않습니다. 따라서 모델링되지 않은 속성을 포함하지 않기 때문에 나중에 모든 속성을 읽을 때 서명이 검증되지 않습니다.

`CLOBBER` 저장 동작을 사용할 수도 있습니다. 이 동작은 낙관적 잠금을 비활성화하고 테이블의 항목을 덮어쓴다는 점을 제외하면 `PUT` 저장 동작과 동일합니다.

서명 오류를 방지하기 위해 DynamoDB Encryption Client는 `AttributeEncryptor`를 저장 동작이 `CLOBBER` 또는 `PUT`로 구성되지 않은 `DynamoDBMapper`와 함께 사용하는 경우 런타임 예외를 발생시킵니다.

예제에 사용된 이 코드를 보려면 [DynamoDBMapper 사용](java-examples.md#java-example-dynamodb-mapper) 및 GitHub의 `aws-dynamodb-encryption-java` 리포지토리에 있는 [AwsKmsEncryptedObject.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedObject.java) 예제를 참조하세요.

## Java의 속성 작업
<a name="attribute-actions-java"></a>

[속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)은 암호화 및 서명되는 속성 값, 서명만 되는 속성 값 및 무시되는 속성 값을 결정합니다. 속성 작업을 지정하는 데 사용하는 메서드는 `DynamoDBMapper` 및 `AttributeEncryptor`, 또는 하위 수준 [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) 중 어느 것을 사용하는지에 따라 달라집니다.

**중요**  
속성 작업을 사용하여 테이블 항목을 암호화한 후 데이터 모델에서 속성을 추가하거나 제거하면 서명 검증 오류가 발생하여 데이터를 복호화하지 못할 수 있습니다. 자세한 내용은 [데이터 모델 변경](data-model.md) 단원을 참조하십시오.

### DynamoDBMapper에 대한 속성 작업
<a name="attribute-action-java-mapper"></a>

`DynamoDBMapper` 및 `AttributeEncryptor`를 사용하는 경우 주석을 사용하여 속성 작업을 지정합니다. DynamoDB Encryption Client는 속성 유형을 정의하는 [표준 DynamoDB 속성 주석](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Annotations.html)을 사용하여 속성을 보호하는 방법을 결정합니다. 기본적으로 기본 키(서명되지만 암호화되지 않음)를 제외하고는 모든 속성이 암호화 및 서명됩니다.

**참고**  
서명할 수 있고 서명해야 하더라도 [@DynamoDBVersionAttribute 주석](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html)을 사용하여 속성 값을 암호화하지 마십시오. 그렇지 않으면 해당 값을 사용하는 조건이 의도하지 않은 영향을 미치게 됩니다.

```
// Attributes are encrypted and signed
@DynamoDBAttribute(attributeName="Description")

// Partition keys are signed but not encrypted
@DynamoDBHashKey(attributeName="Title")

// Sort keys are signed but not encrypted
@DynamoDBRangeKey(attributeName="Author")
```

예외를 지정하려면 DynamoDB Encryption Client for Java에 정의된 암호화 주석을 사용합니다. 클래스 수준에서 지정하면 해당 값이 클래스의 기본값이 됩니다.

```
// Sign only
@DoNotEncrypt

// Do nothing; not encrypted or signed
@DoNotTouch
```

예를 들어 이러한 주석은 `PublicationYear` 속성에 서명하지만 암호화하지는 않으며 `ISBN` 속성 값을 암호화하거나 서명하지 않습니다.

```
// Sign only (override the default)
@DoNotEncrypt
@DynamoDBAttribute(attributeName="PublicationYear")

// Do nothing (override the default)
@DoNotTouch
@DynamoDBAttribute(attributeName="ISBN")
```

### DynamoDBEncryptor에 대한 속성 작업
<a name="attribute-action-default"></a>

[DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html)를 직접 사용하는 경우 속성 작업을 지정하려면 이름-값 페어가 속성 이름 및 지정한 작업을 표현하는 `HashMap` 객체를 만듭니다.

속성 작업에 유효한 값은 `EncryptionFlags` 열거 유형으로 정의되어 있습니다. `ENCRYPT` 및 `SIGN`와 함께 사용하거나 `SIGN` 단독으로 사용하거나 둘 다 생략할 수 있습니다. 하지만 `ENCRYPT` 단독으로 사용하는 경우 DynamoDB Encryption Client에서 오류가 발생합니다. 서명하지 않은 속성은 암호화할 수 없습니다.

```
ENCRYPT
SIGN
```

**주의**  
기본 키 속성은 암호화하지 마십시오. 일반 텍스트로 남겨 두어야 DynamoDB에서 전체 테이블 스캔을 실행하지 않고 해당 항목을 찾을 수 있습니다.

암호화 컨텍스트에서 프라이머리 키를 지정하고 나서 프라이머리 키 속성에 대한 속성 작업에서 `ENCRYPT`를 지정하는 경우 DynamoDB Encryption Client에서 예외가 발생합니다.

예를 들어 다음 Java 코드는 `record` 항목의 모든 속성을 암호화하고 서명하는 `actions` HashMap을 만듭니다. 서명되었지만 암호화되지 않은 파티션 키 및 정렬 키 속성 및 서명되거나 암호화되지 않은 `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: // no break; falls through to next case
    case sortKeyName:
      // Partition and sort keys must not be encrypted, but should be signed
      actions.put(attributeName, signOnly);
      break;
    case "test":
      // Don't encrypt or sign
      break;
    default:
      // Encrypt and sign everything else
      actions.put(attributeName, encryptAndSign);
      break;
  }
}
```

그런 다음 `DynamoDBEncryptor`의 [encryptRecord](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html#encryptRecord-java.util.Map-java.util.Map-com.amazonaws.services.dynamodbv2.datamodeling.encryption.EncryptionContext-) 방법을 호출할 때 맵을 `attributeFlags` 파라미터의 값으로 지정합니다. 예를 들어, `encryptRecord`에 대한 이 호출은 `actions` 맵을 사용합니다.

```
// Encrypt the plaintext record
final Map<String, AttributeValue> encrypted_record = encryptor.encryptRecord(record, actions, encryptionContext);
```

## 테이블 이름 재정의
<a name="override-table-name"></a>

DynamoDB Encryption Client에서 DynamoDB 테이블의 이름은 암호화 및 복호화 메서드에 전달되는[ DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)의 요소입니다. 테이블 항목을 암호화하거나 서명할 때 테이블 이름을 포함한 DynamoDB 암호화 컨텍스트는 암호화 텍스트에 암호로 바인딩됩니다. decrypt 방법에 전달된 DynamoDB 암호화 컨텍스트가 encrypt 방법에 전달된 DynamoDB 암호화 컨텍스트와 일치하지 않으면 복호화 작업이 실패합니다.

테이블을 백업하거나 [특정 시점으로 복구](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/PointInTimeRecovery.html)를 수행할 때와 같이 테이블 이름이 변경되는 경우도 있습니다. 이러한 항목의 서명을 복호화하거나 확인할 때 원래 테이블 이름을 포함하여 항목을 암호화하고 서명하는 데 사용된 것과 동일한 DynamoDB 암호화 컨텍스트를 전달해야 합니다. 현재 테이블 이름은 필요하지 않습니다.

`DynamoDBEncryptor`를 사용하는 경우 DynamoDB 암호화 컨텍스트를 수동으로 결합합니다. 그러나 `DynamoDBMapper`를 사용하는 경우 `AttributeEncryptor`는 현재 테이블 이름을 포함하여 DynamoDB 암호화 컨텍스트를 만듭니다. `AttributeEncryptor`에서 다른 테이블 이름으로 암호화 컨텍스트를 만들도록 지정하려면 `EncryptionContextOverrideOperator`를 사용합니다.

예를 들어 다음 코드에서는 CMP(암호화 자료 공급자) 및 `DynamoDBEncryptor`의 인스턴스를 만듭니다. 그런 다음 `DynamoDBEncryptor`의 `setEncryptionContextOverrideOperator` 메서드를 호출합니다. 하나의 테이블 이름을 재정의하는 `overrideEncryptionContextTableName` 연산자를 사용합니다. 이 방법으로 구성되면 `AttributeEncryptor`는 `oldTableName` 대신 `newTableName`을 포함하는 DynamoDB 암호화 컨텍스트를 생성합니다. 전체 예제는 [EncryptionContextOverridesWithDynamoDBMapper.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/EncryptionContextOverridesWithDynamoDBMapper.java)를 참조하십시오.

```
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, keyArn);
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);

encryptor.setEncryptionContextOverrideOperator(EncryptionContextOperators.overrideEncryptionContextTableName(
                oldTableName, newTableName));
```

항목을 복호화하고 확인하는 `DynamoDBMapper`의 load 메서드를 호출할 때 원래 테이블 이름을 지정합니다.

```
mapper.load(itemClass, DynamoDBMapperConfig.builder()
                .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNameReplacement(oldTableName))
                .build());
```

여러 테이블 이름을 재정의하는 `overrideEncryptionContextTableNameUsingMap` 연산자를 사용할 수도 있습니다.

테이블 이름 재정의 연산자는 일반적으로 데이터를 복호화하고 서명을 확인할 때 사용됩니다. 그러나 암호화 및 서명 시 DynamoDB 암호화 컨텍스트의 테이블 이름을 다른 값으로 설정하는 데 사용할 수 있습니다.

`DynamoDBEncryptor`를 사용하는 경우 테이블 이름 재정의 연산자를 사용하지 마십시오. 대신 원래 테이블 이름으로 암호화 컨텍스트를 만들고 복호화 메서드에 제출하십시오.

# DynamoDB Encryption Client for Java의 예제 코드
<a name="java-examples"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

다음 예제에서는 DynamoDB Encryption Client for Java를 사용하여 애플리케이션에서 DynamoDB 테이블 항목을 보호하는 방법을 보여줍니다. GitHub의 [aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) 리포지토리의 [예제](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples) 디렉터리에서 더 많은 예제를 찾고 직접 제공할 수 있습니다.

**Topics**
+ [DynamoDBEncryptor 사용](#java-example-ddb-encryptor)
+ [DynamoDBMapper 사용](#java-example-dynamodb-mapper)

## DynamoDBEncryptor 사용
<a name="java-example-ddb-encryptor"></a>

이 예제에서는 [Direct KMS Provider](direct-kms-provider.md)와 함께 하위 수준 [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html)를 사용하는 방법을 보여줍니다. 다이렉트 KMS 공급자는 사용자가 지정한 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) in AWS Key Management Service (AWS KMS)에서 암호화 자료를 생성하고 보호합니다.

`DynamoDBEncryptor`와 함께 호환 가능한 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)를 사용할 수 있고 `DynamoDBMapper` 및 [AttributeEncryptor](java-using.md#attribute-encryptor)에서는 Direct KMS Provider를 사용할 수 있습니다.

**전체 코드 샘플 보기**: [AwsKmsEncryptedItem.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedItem.java)

1단계: Direct KMS Provider 생성  
지정된 리전으로 AWS KMS 클라이언트의 인스턴스를 생성합니다. 그런 다음 클라이언트 인스턴스를 사용하여 원하는 AWS KMS key로 Direct KMS Provider의 인스턴스를 생성합니다.  
이 예제에서는 Amazon 리소스 이름(ARN)을 사용하여를 식별 AWS KMS key하지만 [유효한 키 식별자를](https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn) 사용할 수 있습니다.  

```
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 생성  
Direct KMS Provider를 사용하여 `DynamoDBEncryptor` 인스턴스를 생성합니다.  

```
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);
```

4단계: DynamoDB 암호화 컨텍스트 생성  
[DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)에는 테이블 구조와 암호화 및 서명 방법에 대한 정보가 포함되어 있습니다. `DynamoDBMapper`를 사용하는 경우 `AttributeEncryptor`에서 자동으로 암호화 컨텍스트를 생성합니다.  

```
final String tableName = "testTable";

final EncryptionContext encryptionContext = new EncryptionContext.Builder()
    .withTableName(tableName)
    .withHashKeyName(partitionKeyName)
    .withRangeKeyName(sortKeyName)
    .build();
```

5단계: 속성 작업 객체 생성  
[속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)은 암호화 및 서명되는 항목 속성, 서명되기만 하는 속성, 암호화 및 서명되지 않는 속성을 결정합니다.  
Java에서 속성 작업을 지정하려면 속성 이름 및 `EncryptionFlags` 값 페어로 구성된 HashMap을 생성합니다.  
예를 들어, 다음 Java 코드는 서명되었지만 암호화되지 않은 파티션 키 및 정렬 키 속성과 서명되거나 암호화되지 않은 `test` 속성을 제외한 `record` 항목의 모든 속성을 암호화하고 서명하는 `actions` HashMap을 생성합니다.  

```
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단계: 항목 암호화 및 서명  
테이블 항목을 암호화하고 서명하려면 `DynamoDBEncryptor`의 인스턴스에서 `encryptRecord` 방법을 호출합니다. 테이블 항목(`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 사용
<a name="java-example-dynamodb-mapper"></a>

다음 예에서는 [Direct KMS Provider](direct-kms-provider.md)와 함께 DynamoDB 매퍼 도우미 클래스를 사용하는 방법을 보여줍니다. Direct KMS Provider는 사용자가 지정한 AWS Key Management Service (AWS KMS)의 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)로 암호화 자료를 생성 및 보호합니다.

`DynamoDBMapper`와 함께 호환 가능한 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)(CMP)를 사용할 수 있으며, 하위 수준 `DynamoDBEncryptor`오 함께 Direct KMS Provider를 사용할 수 있습니다.

**전체 코드 샘플 보기**: [AwsKmsEncryptedObject.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedObject.java)

1단계: Direct KMS Provider 생성  
지정된 리전으로 AWS KMS 클라이언트의 인스턴스를 생성합니다. 그런 다음 클라이언트 인스턴스를 사용하여 원하는 AWS KMS key로 Direct KMS Provider의 인스턴스를 생성합니다.  
이 예제에서는 Amazon 리소스 이름(ARN)을 사용하여를 식별 AWS KMS key하지만 [유효한 키 식별자를](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id) 사용할 수 있습니다.  

```
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 Encryptor 및 DynamoDBMapper 만들기  
이전 단계에서 생성한 Direct KMS Provider를 사용하여 [DynamoDB Encryptor](java-using.md#attribute-encryptor)의 인스턴스를 생성합니다. DynamoDB Mapper를 사용하려면 하위 수준의 DynamoDB Encryptor를 인스턴스화해야 합니다.  
그런 다음 DynamoDB 데이터베이스 인스턴스와 매퍼 구성을 만들고 이를 사용하여 DynamoDB Mapper의 인스턴스를 만듭니다.  
`DynamoDBMapper`를 사용하여 서명된(또는 암호화 및 서명된) 항목을 추가하거나 편집하는 경우 다음 예와 같이 모든 속성을 포함하는 `PUT`와 같은 [저장 동작을 사용](java-using.md#save-behavior)하도록 구성합니다. 그렇지 않으면 데이터를 복호화하지 못할 수 있습니다.

```
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 테이블을 정의합니다. 주석을 사용하여 [속성 작업](java-using.md#attribute-actions-java)을 지정합니다. 이 예제에서는 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);
```

# DynamoDB Encryption Client for Python
<a name="python"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

이 주제에서는 DynamoDB Encryption Client for Pytho를 설치하고 사용하는 방법을 설명합니다. 시작하는 데 도움이 되는 전체 및 테스트된 [샘플 코드](https://github.com/aws/aws-dynamodb-encryption-python/tree/master/examples)를 포함하여 GitHub의 [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) 리포지토리에서 코드를 찾을 수 있습니다.

**참고**  
DynamoDB Encryption Client for Python의 버전 1.*x*.*x* 및 2.*x*.*x*는 2022년 7월부터 [지원 종료 단계](what-is-database-encryption-sdk.md#support)에 있습니다. 가능한 한 빨리 최신 버전으로 업그레이드하세요.

**Topics**
+ [사전 조건](#python-prerequisites)
+ [설치](#python-installation)
+ [DynamoDB Encryption Client for Python 사용](python-using.md)
+ [Python 예제](python-examples.md)

## 사전 조건
<a name="python-prerequisites"></a>

Amazon DynamoDB Encryption Client for Python를 설치하기 전에 다음 사전 조건이 충족되었는지 확인합니다.

**지원되는 Python 버전**  
Amazon DynamoDB Encryption Client for Python 버전 3.3.0 이상에는 Python 3.8 이상이 필요합니다. Python을 다운로드하려면 [Python 다운로드](https://www.python.org/downloads/)를 참조하세요.  
이전 버전의 Amazon DynamoDB Encryption Client for Python는 Python 2.7 및 Python 3.4 이상을 지원하지만 최신 버전의 DynamoDB Encryption Client를 사용하는 것이 좋습니다.

**Python용 pip 설치 도구**  
Python 3.6 이상에는 **pip**가 포함되어 있지만 업그레이드가 필요할 수도 있습니다. pip 업그레이드 또는 설치에 대한 자세한 내용은 **pip** 설명서의 [설치](https://pip.pypa.io/en/latest/installation/)를 참조하세요.

## 설치
<a name="python-installation"></a>

다음 예제와 같이 **pip**를 사용하여 Amazon DynamoDB Encryption Client for Python를 설치합니다.

**최신 버전 설치**  

```
pip install dynamodb-encryption-sdk
```

**pip**를 사용하여 패키지를 설치 및 업그레이드하는 방법에 대한 자세한 내용은 [패키지 설치](https://packaging.python.org/tutorials/installing-packages/)를 참조하십시오.

DynamoDB Encryption Client에는 모든 플랫폼에 [암호화 라이브러리](https://cryptography.io/en/latest/)가 필요합니다. 모든 버전의 **pip**는 Windows에 **암호화** 라이브러리를 설치하고 빌드합니다. **pip** 8.1 이상은 Linux에 **암호화**를 설치하고 구축합니다. 이전 버전의 **pip**를 사용 중이고 Linux 환경에 **암호**화 라이브러리를 빌드하는 데 필요한 도구가 없는 경우 해당 도구를 설치해야 합니다. 자세한 내용은 [Linux에서 암호화 빌드](https://cryptography.io/en/latest/installation/#building-cryptography-on-linux)를 참조하세요.

GitHub의 [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) 리포지토리에서 DynamoDB Encryption Client의 최신 개발 버전을 얻을 수 있습니다.

DynamoDB Encryption Client를 설치한 후 이 가이드의 Python 코드 예제를 살펴보고 시작하세요.

# DynamoDB Encryption Client for Python 사용
<a name="python-using"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

이 주제에서는 다른 프로그래밍 언어 구현에서는 찾을 수 없는 DynamoDB Encryption Client for Python의 일부 기능에 대해 설명합니다. 이러한 기능은 가장 안전한 방법으로 DynamoDB Encryption Client를 더 쉽게 사용할 수 있도록 설계되었습니다. 특별한 사용 사례가 아니라면 이를 사용하는 것이 좋습니다.

DynamoDB Encryption Client를 사용한 프로그래밍에 대한 자세한 내용은 이 가이드의 [Python 예제](python-examples.md), GitHub의 ws-dynamodb-encryption-pytho 리포지토리의 [예제](https://github.com/aws/aws-dynamodb-encryption-python/tree/master/examples) 및 DynamoDB Encryption Client에 대한 [Python 설명서](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/)를 참조하세요.

**Topics**
+ [클라이언트 헬퍼 클래스](#python-helpers)
+ [TableInfo 클래스](#table-info)
+ [Python의 속성 작업](#python-attribute-actions)

## 클라이언트 헬퍼 클래스
<a name="python-helpers"></a>

DynamoDB Encryption Client for Python에는 DynamoDB용 Boto 3 클래스를 미러링하는 여러 클라이언트 헬퍼 클래스가 포함되어 있습니다. 이러한 헬퍼 클래스는 다음과 같이 기존 DynamoDB 애플리케이션에 암호화 및 서명을 더 쉽게 추가하고 가장 일반적인 문제를 방지할 수 있도록 설계되었습니다.
+ 기본 키에 대한 재정의 작업을 [AttributeActions](#python-attribute-actions) 객체에 추가하거나 `AttributeActions` 객체가 기본 키를 암호화하도록 클라이언트에 명시적으로 지시하는 경우 예외를 발생시키는 방식으로 항목에서 기본 키를 암호화하지 못하도록 합니다. `AttributeActions` 객체의 기본 작업이 `DO_NOTHING`이면 클라이언트 헬퍼 클래스는 프라이머리 키에 대해 해당 작업을 사용합니다. 그렇지 않으면 `SIGN_ONLY`를 사용합니다.
+ [TableInfo 객체](#python-helpers)를 생성하고 DynamoDB 호출을 기반으로 [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)를 채웁니다. 이는 DynamoDB 암호화 컨텍스트가 정확하고 클라이언트가 프라이머리 키를 식별할 수 있도록 하는 데 도움이 됩니다.
+ 테이블에 쓰거나 읽어올 때 사용자 모르게 테이블 항목을 암호화 및 복호화하는 `put_item` 및 `get_item`와 같은 방법을 지원합니다. `update_item` 메소드만 지원되지 않습니다.

하위 수준의 [항목 암호화 도구](DDBEC-legacy-concepts.md#item-encryptor)를 사용하여 직접 상호 작용하는 대신에 클라이언트 헬퍼 클래스를 사용할 수 있습니다. 항목 암호화 도구에서 고급 옵션을 설정해야 하는 경우가 아니면 이 클래스를 사용합니다.

클라이언트 헬퍼 클래스에는 다음이 포함됩니다.
+ DynamoDB의 [테이블](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#table) 리소스를 사용하여 한 번에 하나의 테이블을 처리하는 애플리케이션을 위한 [EncryptedTable](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/table.html#module-dynamodb_encryption_sdk.encrypted.table).
+ 일괄 처리를 위해 DynamoDB의 [서비스 리소스](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#service-resource) 클래스를 사용하는 애플리케이션을 위한 [EncryptedResource](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/resource.html).
+ DynamoDB에서 [하위 수준 클라이언트](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#client)를 사용하는 애플리케이션을 위한 [EncryptedClient](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/client.html).

클라이언트 헬퍼 클래스를 사용하려면 호출자에게 대상 테이블에서 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 작업을 호출할 수 있는 권한이 있어야 합니다.

## TableInfo 클래스
<a name="table-info"></a>

[TableInfo](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/tools/structures.html#dynamodb_encryption_sdk.structures.TableInfo) 클래스는 프라이머리 키 및 보조 인덱스에 대한 필드가 포함된 DynamoDB 테이블을 나타내는 헬퍼 클래스입니다. 테이블에 대한 정확한 실시간 정보를 얻는 데 도움이 됩니다.

[클라이언트 헬퍼 클래스](#python-helpers)를 사용하는 경우 이 클래스에서 사용자를 대신하여 `TableInfo` 객체를 만들고 사용합니다. 그렇지 않으면 명시적으로 생성할 수 있습니다. 예제는 [항목 암호화 도구 사용](python-examples.md#python-example-item-encryptor) 섹션을 참조하세요.

`TableInfo` 객체에 대해 `refresh_indexed_attributes` 방법을 호출하면 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 작업을 호출하여 객체의 속성 값이 채워집니다. 테이블 쿼리는 하드 코딩된 인덱스 이름보다 훨씬 더 안정적입니다. `TableInfo` 클래스에는 [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)에 필요한 값을 제공하는 `encryption_context_values` 속성도 포함되어 있습니다.

`refresh_indexed_attributes` 방법을 사용하려면 호출자에게 대상 테이블에서 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 작업을 호출할 수 있는 권한이 있어야 합니다.

## Python의 속성 작업
<a name="python-attribute-actions"></a>

[속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)은 항목의 각 속성에 대해 수행할 작업을 항목 암호화 도구에 알려줍니다. Python에서 속성 작업을 지정하려면 기본 작업과 특정 속성에 대한 예외가 포함된 `AttributeActions` 객체를 만듭니다. 유효한 값은 `CryptoAction` 열거 유형에 정의됩니다.

**중요**  
속성 작업을 사용하여 테이블 항목을 암호화한 후 데이터 모델에서 속성을 추가하거나 제거하면 서명 검증 오류가 발생하여 데이터를 복호화하지 못할 수 있습니다. 자세한 내용은 [데이터 모델 변경](data-model.md) 단원을 참조하십시오.

```
DO_NOTHING = 0
SIGN_ONLY = 1
ENCRYPT_AND_SIGN = 2
```

예를 들어, 이 `AttributeActions` 객체는 모든 속성에 대한 기본값을 `ENCRYPT_AND_SIGN`으로 설정하고 `ISBN` 및 `PublicationYear` 속성에 대한 예외를 지정합니다.

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={
        'ISBN': CryptoAction.DO_NOTHING,
        'PublicationYear': CryptoAction.SIGN_ONLY
    }
)
```

[클라이언트 헬퍼 클래스](#python-helpers)를 사용하는 경우 기본 키 속성에 대한 속성 작업을 지정할 필요가 없습니다. 클라이언트 헬퍼 클래스는 프라이머리 키를 암호화하는 것을 방지합니다.

클라이언트 헬퍼 클래스를 사용하지 않고 프라이머리 작업이`ENCRYPT_AND_SIGN` 인 경우 프라이머리 키에 대한 작업을 지정해야 합니다. 프라이머리 키에 대한 권장 조치는 `SIGN_ONLY`입니다. 이를 쉽게 하려면 프라이머리 키에 SIGN\$1ONLY를 사용하거나 기본 작업인 경우 DO\$1NOTHING을 사용하는 `set_index_keys` 방법을 사용합니다.

**주의**  
기본 키 속성은 암호화하지 마십시오. 일반 텍스트로 남겨 두어야 DynamoDB에서 전체 테이블 스캔을 실행하지 않고 해당 항목을 찾을 수 있습니다.

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
)
actions.set_index_keys(*table_info.protected_index_keys())
```

# DynamoDB Encryption Client for Python의 예제 코드
<a name="python-examples"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

다음 예제에서는 DynamoDB Encryption Client for Python를 사용하여 애플리케이션에서 DynamoDB 데이터를 보호하는 방법을 보여줍니다. GitHub에 있는 [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) 리포지토리의 [예제](https://github.com/aws/aws-dynamodb-encryption-python/tree/master/examples) 디렉터리에서 더 많은 예제를 찾고 직접 기여할 수 있습니다.

**Topics**
+ [EncryptedTable 클라이언트 헬퍼 클래스 사용](#python-example-table)
+ [항목 암호화 도구 사용](#python-example-item-encryptor)

## EncryptedTable 클라이언트 헬퍼 클래스 사용
<a name="python-example-table"></a>

다음 예제에서는 [Direct KMS Provider](direct-kms-provider.md)를 `EncryptedTable` [클라이언트 헬퍼 클래스](python-using.md#python-helpers)와 함께 사용하는 방법을 보여줍니다. 이 예제에서는 다음 [항목 암호화 도구 사용](#python-example-item-encryptor) 예제와 동일한 [암호화 자료 공급자](DDBEC-legacy-concepts.md#concept-material-provider)를 사용합니다. 그러나 하위 수준 [항목 암호화 도구](DDBEC-legacy-concepts.md#item-encryptor)와 직접 상호 작용하는 대신 `EncryptedTable` 클래스를 사용합니다.

이러한 예제를 비교하면 클라이언트 도우미 클래스가 수행하는 작업을 확인할 수 있습니다. 여기에는 [DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)를 생성하거나 프라이머리 키 속성을 항상 서명하되 절대로 암호화되지 않은 상태로 유지하는 등의 작업이 포함됩니다. 암호화 컨텍스트를 만들고 프라이머리 키를 검색하기 위해 클라이언트 헬퍼 클래스는 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 작업을 호출합니다. 이 코드를 실행하려면 이 작업을 호출할 수 있는 권한이 있어야 합니다.

**전체 코드 샘플 보기**: [aws\$1kms\$1encrypted\$1table.py](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_table.py)

1단계: 테이블 만들기  
테이블 이름을 사용하여 표준 DynamoDB 테이블의 인스턴스를 생성하는 것부터 시작합니다.  

```
table_name='test-table'
table = boto3.resource('dynamodb').Table(table_name)
```

2단계: 암호화 자료 공급자 생성  
선택한 [암호화 자료 공급자](crypto-materials-providers.md)(CMP)의 인스턴스를 생성합니다.  
이 예제에서는 [Direct KMS Provider](direct-kms-provider.md)를 사용하지만, 사용자는 모든 호환되는 CMP를 사용할 수 있습니다. Direct KMS Provider를 생성하려면 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)를 지정합니다. 이 예제에서는의 Amazon 리소스 이름(ARN)을 사용하지 AWS KMS key만 유효한 키 식별자를 사용할 수 있습니다.  

```
kms_key_id='arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
```

3단계: 속성 작업 객체 생성  
[속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)은 항목의 각 속성에 대해 수행할 작업을 항목 암호화 도구에 알려줍니다. 이 예제의 `AttributeActions` 객체는 무시되는 `test` 속성을 제외한 모든 항목을 암호화하고 서명합니다.  
클라이언트 도우미 클래스를 사용할 때 프라이머리 키 속성에 대한 속성 작업을 지정하지 않습니다. `EncryptedTable` 클래스는 프라이머리 키 속성을 서명하지만 암호화하지는 않습니다.  

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={'test': CryptoAction.DO_NOTHING}
)
```

4단계: 암호화된 테이블 생성  
표준 테이블, Direct KMS Provider 및 속성 작업을 사용하여 암호화된 테이블을 생성합니다. 이 단계로 구성이 완료됩니다.  

```
encrypted_table = EncryptedTable(
    table=table,
    materials_provider=kms_cmp,
    attribute_actions=actions
)
```

5단계: 테이블에 일반 텍스트 항목 넣기  
`encrypted_table`에 대한 `put_item` 방법을 호출하면 테이블 항목이 투명하게 암호화되고 서명되어 DynamoDB 테이블에 추가됩니다.  
먼저 테이블 항목을 정의합니다.  

```
plaintext_item = {
    'partition_attribute': 'value1',
    'sort_attribute': 55
    'example': 'data',
    'numbers': 99,
    'binary': Binary(b'\x00\x01\x02'),
    'test': 'test-value'
}
```
그런 다음 테이블에 넣습니다.  

```
encrypted_table.put_item(Item=plaintext_item)
```

암호화된 형식으로 DynamoDB 테이블에서 항목을 가져오려면 `table` 객체에 대한 `get_item` 방법을 호출합니다. 복호화된 항목을 얻으려면 `encrypted_table` 객체에 대한 `get_item` 메서드를 호출합니다.

## 항목 암호화 도구 사용
<a name="python-example-item-encryptor"></a>

이 예제에서는 테이블 항목을 암호화할 때 항목 암호화 도구와 상호 작용하는 [클라이언트 헬퍼 클래스](python-using.md#python-helpers)를 사용하는 대신 DynamoDB Encryption Client의 [항목 암호화 도구](DDBEC-legacy-concepts.md#item-encryptor)와 직접 상호 작용하는 방법을 보여줍니다.

이 기술을 사용하면 DynamoDB 암호화 컨텍스트와 구성 객체(`CryptoConfig`)를 수동으로 생성합니다. 또한 한 번의 호출로 항목을 암호화하고 별도의 호출로 DynamoDB 테이블에 넣습니다. 이를 통해 `put_item` 호출을 사용자 지정하고 DynamoDB Encryption Client를 사용하여 DynamoDB로 전송되지 않는 구조화된 데이터를 암호화하고 서명할 수 있습니다.

이 예제에서는 [Direct KMS Provider](direct-kms-provider.md)를 사용하지만, 사용자는 모든 호환되는 CMP를 사용할 수 있습니다.

**전체 코드 샘플 보기**: [aws\$1kms\$1encrypted\$1item.py](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_item.py)

1단계: 테이블 만들기  
테이블 이름을 사용하여 표준 DynamoDB 테이블 리소스의 인스턴스를 생성하는 것부터 시작합니다.  

```
table_name='test-table'
table = boto3.resource('dynamodb').Table(table_name)
```

2단계: 암호화 자료 공급자 생성  
선택한 [암호화 자료 공급자](crypto-materials-providers.md)(CMP)의 인스턴스를 생성합니다.  
이 예제에서는 [Direct KMS Provider](direct-kms-provider.md)를 사용하지만, 사용자는 모든 호환되는 CMP를 사용할 수 있습니다. Direct KMS Provider를 생성하려면 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)를 지정합니다. 이 예제에서는의 Amazon 리소스 이름(ARN)을 사용하지 AWS KMS key만 유효한 키 식별자를 사용할 수 있습니다.  

```
kms_key_id='arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
```

3단계: TableInfo 헬퍼 클래스 사용  
DynamoDB에서 테이블에 대한 정보를 얻으려면 [TableInfo](python-using.md#python-helpers) 헬퍼 클래스의 인스턴스를 생성합니다. 항목 암호화 도구로 직접 작업하는 경우 `TableInfo` 인스턴스를 생성하고 해당 메서드를 호출해야 합니다. [클라이언트 헬퍼 클래스](python-using.md#python-helpers)가 사용자를 대신하여 이 작업을 수행합니다.  
`TableInfo`의 `refresh_indexed_attributes` 메소드는 [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) DynamoDB 작업을 사용하여 테이블에 대한 정확한 정보를 실시간으로 가져옵니다. 여기에는 프라이머리 키와 로컬 및 글로벌 보조 인덱스가 포함됩니다. 호출자에게 `DescribeTable`을 호출할 수 있는 권한이 있어야 합니다.  

```
table_info = TableInfo(name=table_name)
table_info.refresh_indexed_attributes(table.meta.client)
```

4단계: DynamoDB 암호화 컨텍스트 생성  
[DynamoDB 암호화 컨텍스트](concepts.md#encryption-context)에는 테이블 구조와 암호화 및 서명 방법에 대한 정보가 포함되어 있습니다. 이 예제에서는 항목 암호화 도구와 상호 작용하므로 DynamoDB 암호화 컨텍스트를 명시적으로 생성합니다. [클라이언트 헬퍼 클래스](python-using.md#python-helpers)는 DynamoDB 암호화 컨텍스트를 생성합니다.  
[TableInfo](python-using.md#python-helpers) 헬퍼 클래스의 속성을 사용하여 파티션 키와 정렬 키를 가져올 수 있습니다.  

```
index_key = {
    'partition_attribute': 'value1',
    'sort_attribute': 55
}

encryption_context = EncryptionContext(
    table_name=table_name,
    partition_key_name=table_info.primary_index.partition,
    sort_key_name=table_info.primary_index.sort,
    attributes=dict_to_ddb(index_key)
)
```

5단계: 속성 작업 객체 생성  
[속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)은 항목의 각 속성에 대해 수행할 작업을 항목 암호화 도구에 알려줍니다. 이 예제의 `AttributeActions` 객체는 서명되었지만 암호화되지 않은 프라이머리 키 속성과 무시되는 `test` 속성을 제외한 모든 항목을 암호화하고 서명합니다.  
항목 암호화 도구와 직접 상호작용하고 기본 작업이 `ENCRYPT_AND_SIGN`인 경우 프라이머리 키에 대한 대체 작업을 지정해야 합니다. 프라이머리 키에 대한 `SIGN_ONLY`을 사용하거나 기본 작업인 경우 `DO_NOTHING`을 사용하는 `set_index_keys` 메서드를 사용할 수 있습니다.  
프라이머리 키를 지정하기 위해 이 예제에서는 DynamoDB 호출로 채워지는 [TableInfo](python-using.md#python-helpers) 객체의 인덱스 키를 사용합니다. 이 기술은 프라이머리 키 이름을 하드 코딩하는 것보다 안전합니다.  

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={'test': CryptoAction.DO_NOTHING}
)
actions.set_index_keys(*table_info.protected_index_keys())
```

6단계: 항목에 대한 구성 만들기  
DynamoDB Encryption Client를 구성하려면 테이블 항목에 대한 [CryptoConfig](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/config.html) 구성에서 방금 생성한 객체를 사용합니다. 클라이언트 헬퍼 클래스는 사용자를 위해 CryptoConfig를 만듭니다.  

```
crypto_config = CryptoConfig(
    materials_provider=kms_cmp,
    encryption_context=encryption_context,
    attribute_actions=actions
)
```

7단계: 항목 암호화  
이 단계에서는 항목을 암호화하고 서명하지만 DynamoDB 테이블에 저장하지는 않습니다.  
클라이언트 헬퍼 클래스를 사용할 경우 항목이 사용자 모르게 암호화 및 서명된 다음, 사용자가 헬퍼 클래스의 `put_item` 메서드를 호출할 때 DynamoDB 테이블에 추가됩니다. 항목 암호화 도구를 직접 사용하는 경우 암호화 및 입력 작업은 독립적입니다.  
먼저 일반 텍스트 항목을 만듭니다.  

```
plaintext_item = {
    'partition_attribute': 'value1',
    'sort_key': 55,
    'example': 'data',
    'numbers': 99,
    'binary': Binary(b'\x00\x01\x02'),
    'test': 'test-value'
}
```
그런 다음 암호화하고 서명합니다. `encrypt_python_item` 방법에는 `CryptoConfig` 구성 객체가 필요합니다.  

```
encrypted_item = encrypt_python_item(plaintext_item, crypto_config)
```

8단계: 테이블에 항목 넣기  
이 단계에서는 암호화되고 서명된 항목을 DynamoDB 테이블에 넣습니다.  

```
table.put_item(Item=encrypted_item)
```

암호화된 항목을 보려면 `encrypted_table` 객체 대신 원본 `table` 객체에 대한 `get_item` 방법을 호출합니다. 항목을 확인 및 복호화하지 않고 DynamoDB 테이블에서 항목을 가져옵니다.

```
encrypted_item = table.get_item(Key=partition_key)['Item']
```

다음 이미지는 암호화되고 서명된 테이블 항목 예제의 일부를 보여줍니다.

암호화된 속성 값은 이진 데이터입니다. 프라이머리 키 속성(`partition_attribute` 및 `sort_attribute`)의 이름과 값 및 `test` 속성은 일반 텍스트로 유지됩니다. 이 출력은 서명(`*amzn-ddb-map-sig*`)을 포함하는 속성과 [자료 설명 속성](DDBEC-legacy-concepts.md#legacy-material-description)(`*amzn-ddb-map-desc*`)을 보여줍니다.

![\[암호화 및 서명된 항목(발췌)\]](http://docs.aws.amazon.com/ko_kr/database-encryption-sdk/latest/devguide/images/encrypted-item-closeup.png)


# 데이터 모델 변경
<a name="data-model"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

항목을 암호화하거나 복호화할 때마다 암호화하고 서명할 속성, 서명할 속성(암호화하지 않음), 무시할 속성을 DynamoDB Encryption Client에 알려주는 [속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)을 제공해야 합니다. 속성 작업은 암호화된 항목에 저장되지 않으며 DynamoDB Encryption Client는 속성 작업을 자동으로 업데이트하지 않습니다.

**중요**  
DynamoDB Encryption Client는 암호화되지 않은 기존 DynamoDB 테이블 데이터의 암호화를 지원하지 않습니다.

데이터 모델을 변경할 때마다, 즉 테이블 항목에서 속성을 추가하거나 제거할 때 오류가 발생할 수 있습니다. 지정한 속성 작업이 항목의 모든 속성을 고려하지 않는 경우 항목이 의도한 방식으로 암호화되고 서명되지 않을 수 있습니다. 특히, 항목 복호화 시 제공하는 속성 작업과 항목 암호화 시 제공했던 속성 작업이 다른 경우 서명 확인이 실패할 수 있습니다.

예를 들어, 항목을 암호화하는 데 사용된 속성 동작에서 `test` 속성에 서명하도록 지정하는 경우 항목의 서명에는 `test` 속성이 포함됩니다. 그러나 항목을 복호화하는 데 사용된 속성 작업이 `test` 속성을 고려하지 않는 경우 클라이언트가 `test` 속성을 포함하지 않는 서명을 확인하려고 하기 때문에 확인이 실패합니다.

이는 DynamoDB Encryption Client가 모든 애플리케이션의 항목에 대해 동일한 서명을 계산해야 하기 때문에 여러 애플리케이션이 동일한 DynamoDB 항목을 읽고 쓸 때 특히 문제가 됩니다. 또한 속성 작업의 변경 사항이 모든 호스트에 전파되어야 하기 때문에 분산 애플리케이션에서도 문제가 됩니다. 한 프로세스에서 한 호스트가 DynamoDB 테이블에 액세스하는 경우에도 모범 사례 프로세스를 설정하면 프로젝트가 더욱 복잡해지더라도 오류를 방지하는 데 도움이 됩니다.

테이블 항목을 읽을 수 없도록 하는 서명 유효성 검사 오류를 방지하려면 다음 지침을 따르십시오.
+ [속성 추가](#add-attribute) - 새 속성이 속성 작업을 변경하는 경우 항목에 새 속성을 포함하기 전에 속성 작업 변경을 완전히 배포합니다.
+ [속성 제거](#remove-attribute) - 항목에서 속성 사용을 중지하는 경우 속성 작업을 변경하지 마십시오.
+ 작업 변경 - 속성 작업 구성을 사용하여 테이블 항목을 암호화한 후에는 테이블의 모든 항목을 다시 암호화하지 않고는 기존 속성에 대한 기본 작업이나 작업을 안전하게 변경할 수 없습니다.

서명 유효성 검사 오류는 해결하기가 매우 어려울 수 있으므로 가장 좋은 방법은 오류를 방지하는 것입니다.

**Topics**
+ [속성 추가](#add-attribute)
+ [속성 제거](#remove-attribute)

## 속성 추가
<a name="add-attribute"></a>

테이블 항목에 새 속성을 추가할 때 속성 작업을 변경해야 할 수 있습니다. 서명 유효성 검사 오류를 방지하려면 2단계 프로세스로 이 변경을 구현하는 것이 좋습니다. 첫 번째 단계가 완료되었는지 확인한 후 두 번째 단계를 시작합니다.

1. 테이블을 읽거나 쓰는 모든 애플리케이션에서 속성 작업을 변경합니다. 이러한 변경 사항을 배포하고 업데이트가 모든 대상 호스트에 전파되었는지 확인합니다.

1. 테이블 항목의 새 속성에 값을 씁니다.

이 2단계 접근 방식은 모든 애플리케이션과 호스트에 동일한 속성 작업이 있도록 하며, 새 속성이 발생하기 전에 동일한 서명을 계산합니다. 일부 암호화의 기본값은 암호화 및 서명이기 때문에 속성에 대한 작업이 *아무 작업 안 함*(암호화 또는 서명 안 함)인 경우에도 중요합니다.

다음 예제에서는 이 프로세스의 첫 번째 단계에 대한 코드를 보여 줍니다. 다른 테이블 항목에 대한 링크를 저장하는 새 항목 속성인 `link`를 추가합니다. 이 링크는 일반 텍스트로 유지되어야 하므로 이 예제에서는 서명 전용 작업을 할당합니다. 이 변경 사항을 완전히 배포한 다음 모든 애플리케이션과 호스트에 새 속성 작업이 있는지 확인한 후 테이블 항목에서 `link` 속성을 사용할 수 있습니다.

------
#### [ Java DynamoDB Mapper ]

`DynamoDB Mapper` 및 `AttributeEncryptor`를 사용하는 경우 기본적으로 기본 키(서명되지만 암호화되지 않음)를 제외하고는 모든 속성이 암호화 및 서명됩니다. 서명 전용 작업을 지정하려면 `@DoNotEncrypt` 주석을 사용합니다.

이 예제에서는 새 `link` 속성에 대한 `@DoNotEncrypt` 주석을 사용합니다.

```
@DynamoDBTable(tableName = "ExampleTable")
public static final class DataPoJo {
  private String partitionAttribute;
  private int sortAttribute;
  private String link;

  @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 = "link")
  @DoNotEncrypt
  public String getLink() {
    return link;
  }

  public void setLink(String link) {
    this.link = link;
  }

  @Override
  public String toString() {
    return "DataPoJo [partitionAttribute=" + partitionAttribute + ",
        sortAttribute=" + sortAttribute + ",
        link=" + link + "]";
  }
}
```

------
#### [ Java DynamoDB encryptor ]

 하위 수준 DynamoDB 암호화 도구에서 각 속성에 대한 작업을 설정해야 합니다. 이 예제에서는 기본값이 `encryptAndSign`인 switch 문을 사용하며, 파티션 키, 정렬 키 및 새 `link` 속성에 대해서는 예외가 지정됩니다. 이 예제에서 링크 속성 코드가 사용되기 전에 완전히 배포되지 않은 경우 링크 속성은 일부 애플리케이션에서 암호화되고 서명되지만 다른 애플리케이션에서는 서명만 됩니다.

```
for (final String attributeName : record.keySet()) {
    switch (attributeName) {
        case partitionKeyName:
            // fall through to the next case
        case sortKeyName:
            // partition and sort keys must be signed, but not encrypted
            actions.put(attributeName, signOnly);
            break;
        case "link":
            // only signed
            actions.put(attributeName, signOnly);
            break;
        default:
            // Encrypt and sign all other attributes
            actions.put(attributeName, encryptAndSign);
            break;
    }
}
```

------
#### [ Python ]

DynamoDB Encryption Client for Python에서는 모든 속성에 대한 기본 작업을 지정한 다음 예외를 지정할 수 있습니다.

Python [클라이언트 헬퍼 클래스](python-using.md#python-helpers)를 사용하는 경우 기본 키 속성에 대한 속성 작업을 지정할 필요가 없습니다. 클라이언트 헬퍼 클래스는 프라이머리 키를 암호화하는 것을 방지합니다. 그러나 클라이언트 도우미 클래스를 사용하지 않는 경우 파티션 키 및 정렬 키에 대해 SIGN\$1ONLY 작업을 설정해야 합니다. 실수로 파티션 또는 정렬 키를 암호화한 경우 전체 테이블 스캔 없이는 데이터를 복구할 수 없습니다.

이 예제에서는 `SIGN_ONLY` 작업을 가져오는 새 `link` 속성에 대한 예외를 지정합니다.

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={
      'example': CryptoAction.DO_NOTHING,  
      'link': CryptoAction.SIGN_ONLY
    }
)
```

------

## 속성 제거
<a name="remove-attribute"></a>

DynamoDB Encryption Client로 암호화된 항목에 더 이상 속성이 필요하지 않은 경우 속성 사용을 중지할 수 있습니다. 그러나 해당 속성에 대한 작업을 삭제하거나 변경하지 마십시오. 그런 경우 해당 속성을 가진 항목이 발견되면 해당 항목에 대해 계산된 서명이 원래 서명과 일치하지 않으므로 서명 유효성 검사가 실패합니다.

코드에서 속성의 모든 추적을 제거하고 싶을 수도 있지만 항목을 삭제하는 대신 더 이상 사용되지 않는다는 설명을 추가합니다. 전체 테이블 스캔을 수행하여 속성의 모든 인스턴스를 삭제하더라도 해당 속성을 가진 암호화된 항목이 캐싱되거나 구성 어딘가에서 처리 중일 수 있습니다.

# DynamoDB Encryption Client 애플리케이션의 문제 해결
<a name="troubleshooting"></a>

**참고**  
클라이언트측 암호화 라이브러리의 [이름이 AWS Database Encryption SDK로 변경되었습니다](DDBEC-rename.md). 다음 주제에서는 Java용 DynamoDB Encryption Client 버전 1.*x*\$12.*x* 와 Python용 DynamoDB Encryption Client 버전 1.*x*\$13.*x*에 대한 정보를 제공합니다. 자세한 내용은 [AWS Database Encryption SDK for DynamoDB 버전 지원](legacy-dynamodb-encryption-client.md#legacy-support)을 참조하세요.

이 섹션에서는 DynamoDB Encryption Client를 사용할 때 발생할 수 있는 문제를 설명하고 문제 해결을 위한 제안을 제공합니다.

DynamoDB Encryption Client에 대한 피드백을 제공하려면 [aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) 또는 [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) GitHub 리포지토리에 문제를 제출하세요.

이 설명서에 대한 피드백을 제공하려면 이 페이지의 피드백 링크를 사용하십시오.

**Topics**
+ [액세스 거부됨](#kms-permissions)
+ [서명 확인 실패](#change-data-model)
+ [이전 버전 글로벌 테이블 관련 문제](#fix-global-tables)
+ [Most Recent Provider의 성능 저하](#mrp-ttl-delay)

## 액세스 거부됨
<a name="kms-permissions"></a>

**문제**: 필요한 리소스에 대한 애플리케이션의 액세스가 거부됩니다.

**제안**: 필요한 권한에 대해 알아보고 이러한 권한을 애플리케이션이 실행되는 보안 컨텍스트에 추가합니다.

**세부 정보**

DynamoDB Encryption Client 라이브러리를 사용하는 애플리케이션을 실행하려면, 호출자에게 해당 구성 요소를 사용할 수 있는 권한이 있어야 합니다. 그렇지 않으면 필수 요소에 대한 액세스가 거부됩니다.
+ DynamoDB Encryption Client에는 Amazon Web Services(AWS) 계정이 필요하지 않으며 어떤 AWS 서비스에도 의존하지 않습니다. 그러나 애플리케이션에서 [를 AWS 계정](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/) 사용하는 경우 계정을 사용할 [권한이 있는 및 사용자가](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html) AWS필요합니다.
+ DynamoDB Encryption Client에는 Amazon DynamoDB가 필요하지 않습니다. 그러나 클라이언트를 사용하는 애플리케이션이 DynamoDB 테이블을 생성하거나, 테이블에 항목을 넣거나, 테이블에서 항목을 가져오는 경우 호출자는 AWS 계정에 필요한 DynamoDB 작업을 사용할 수 있는 권한이 있어야 합니다. 자세한 내용은 *Amazon DynamoDB 개발자 안내서*의 [액세스 제어 주제](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/access-control-overview.html)를 참조하세요.
+ 애플리케이션이 DynamoDB Encryption Client for Python의 [클라이언트 헬퍼 클래스](python-using.md#python-helpers)를 사용하는 경우 호출자는 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 작업을 호출할 권한이 있어야 합니다.
+ DynamoDB Encryption Client에는 AWS Key Management Service ()가 필요하지 않습니다AWS KMS. 그러나 애플리케이션이 [Direct KMS Materials Provider](direct-kms-provider.md)를 사용하거나가 사용하는 공급자 스토어와 함께 [Most Recent Provider](most-recent-provider.md)를 사용하는 경우 AWS KMS호출자는 AWS KMS [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) 및 [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) 작업을 사용할 수 있는 권한이 있어야 합니다.

## 서명 확인 실패
<a name="change-data-model"></a>

**문제**: 서명 확인 실패로 인해 항목을 복호화할 수 없습니다. 또한 항목이 의도한 대로 암호화 및 서명되지 않을 수도 있습니다.

**제안**: 제공하는 속성 작업에서 항목의 모든 속성을 고려해야 합니다. 항목을 복호화할 때는 항목을 암호화하는 데 사용된 작업과 일치하는 속성 작업을 제공해야 합니다.

**세부 정보**

제공하는 [속성 작업](DDBEC-legacy-concepts.md#legacy-attribute-actions)은 암호화하고 서명할 속성, 서명할(암호화하지 않음) 속성, 무시할 속성을 DynamoDB Encryption Client에 알려줍니다.

지정한 속성 작업이 항목의 모든 속성을 고려하지 않는 경우 항목이 의도한 방식으로 암호화되고 서명되지 않을 수 있습니다. 항목 복호화 시 제공하는 속성 작업과 항목 암호화 시 제공했던 속성 작업이 다른 경우 서명 확인이 실패할 수 있습니다. 이는 새 속성 동작이 모든 호스트에 전파되지 않았을 수 있는 분산 애플리케이션에서 특히 발생하는 문제입니다.

서명 유효성 검사 오류는 해결하기 어렵습니다. 이를 방지하기 위해 데이터 모델을 변경할 때 추가 예방 조치를 취하십시오. 자세한 내용은 [데이터 모델 변경](data-model.md)을 참조하세요.

## 이전 버전 글로벌 테이블 관련 문제
<a name="fix-global-tables"></a>

**문제**: 서명 확인에 실패하여 이전 버전의 Amazon DynamoDB 글로벌 테이블의 항목을 복호화할 수 없습니다.

**제안**: 예약된 복제 필드가 암호화되거나 서명되지 않도록 속성 작업을 설정합니다.

**세부 정보**

DynamoDB Encryption Client를 [DynamoDB 글로벌 테이블](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)과 함께 사용할 수 있습니다. [다중 리전 KMS 키](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)와 함께 글로벌 테이블을 사용하고 글로벌 테이블이 복제되는 모든 AWS 리전 에 KMS 키를 복제하는 것이 좋습니다.

글로벌 테이블 [버전 2019.11.21](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html)부터 DynamoDB Encryption Client에서 특별한 구성 없이 글로벌 테이블을 사용할 수 있습니다. 하지만 글로벌 테이블 [버전 2017.11.29](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html)를 사용하는 경우 예약된 복제 필드가 암호화되거나 서명되지 않았는지 확인해야 합니다.

[글로벌 테이블 버전 2017.11.29를 사용하는 경우 다음 속성에 대한 속성 작업을 [Java](java-using.md#attribute-actions-java)의 `DO_NOTHING` 또는 Python](python-using.md#python-attribute-actions)의 `@DoNotTouch`으로 설정해야 합니다.
+ `aws:rep:deleting`
+ `aws:rep:updatetime`
+ `aws:rep:updateregion`

다른 버전의 글로벌 테이블을 사용하는 경우에는 별도의 조치가 필요하지 않습니다.

## Most Recent Provider의 성능 저하
<a name="mrp-ttl-delay"></a>

**문제**: 특히 최신 버전의 DynamoDB Encryption Client로 업데이트한 후 애플리케이션의 응답성이 떨어집니다.

**제안**: Time-to-Live 값과 캐시 크기를 조정합니다.

**세부 정보**

Most Recent Provider는 암호화 자료의 재사용을 제한적으로 허용하여 DynamoDB Encryption Client를 사용하는 애플리케이션의 성능을 개선하도록 설계되었습니다. 애플리케이션에 Most Recent Provider를 구성할 때는 성능 향상과 캐싱 및 재사용으로 인해 발생하는 보안 문제 사이에서 균형을 맞춰야 합니다.

최신 버전의 DynamoDB Encryption Client에서는 time-to-live(TTL) 값에 따라 캐시된 암호화 자료 공급자(CMP)를 사용할 수 있는 기간이 결정됩니다. 또한 TTL은 Most Recent Provider가 CMP의 새 버전을 확인하는 빈도를 결정합니다.

TTL이 너무 길면 애플리케이션이 비즈니스 규칙이나 보안 표준을 위반할 수 있습니다. TTL이 너무 짧은 경우 공급자 스토어를 자주 호출하면 공급자 스토어가 애플리케이션 및 서비스 계정을 공유하는 기타 애플리케이션의 요청을 제한할 수 있습니다. 이 문제를 해결하려면 지연 시간 및 가용성 목표를 충족하고 보안 표준을 준수하는 값으로 TTL 및 캐시 크기를 조정합니다. 자세한 내용은 [time-to-live 값 설정](most-recent-provider.md#most-recent-provider-ttl) 섹션을 참조하십시오.