

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

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


****  

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

검색 가능한 암호화를 사용하면 전체 데이터베이스를 복호화하지 않고도 암호화된 레코드를 검색할 수 있습니다. 이는 필드에 기록된 일반 텍스트 값과 데이터베이스에 실제로 저장된 암호화된 값 사이의 맵을 생성하는 *비컨*을 사용하여 수행됩니다. AWS Database Encryption SDK는 레코드에 추가하는 새 필드에 비컨을 저장합니다. 사용하는 비컨의 유형에 따라 암호화된 데이터에 대해 정확히 일치하는 검색을 수행하거나 보다 맞춤화된 복합 쿼리를 수행할 수 있습니다.

**참고**  
 AWS Database Encryption SDK의 검색 가능한 암호화는 검색 가능한 대칭 암호화와 같이 학술 연구에 정의된 [검색 가능한 대칭 암호화](https://dl.acm.org/doi/10.1145/1180405.1180417)와 다릅니다.



비컨은 필드의 일반 텍스트와 암호화된 값 사이에 맵을 생성하는 잘린 해시 기반 메시지 인증 코드(HMAC) 태그입니다. 검색 가능한 암호화를 위해 구성된 암호화된 필드에 새 값을 작성하면 AWS Database Encryption SDK가 일반 텍스트 값을 통해 HMAC를 계산합니다. 이 HMAC 출력은 해당 필드의 일반 텍스트 값과 일대일(1:1) 일치합니다. 여러 개의 고유한 일반 텍스트 값이 잘린 동일한 HMAC 태그에 매핑되도록 HMAC 출력이 잘립니다. 이러한 오탐은 일반 텍스트 값에 대한 구별 정보를 식별하는 권한이 없는 사용자의 능력을 제한합니다. 비컨을 쿼리하면 AWS Database Encryption SDK는 이러한 오탐을 자동으로 필터링하고 쿼리의 일반 텍스트 결과를 반환합니다.

각 비컨에 대해 생성된 평균 오탐 수는 잘린 후 남은 비컨 길이에 따라 결정됩니다. 구현에 적합한 비컨 길이를 결정하는 데 도움이 필요하면 [비컨 길이 결정](choosing-beacon-length.md)을 참조하세요.

**참고**  
검색 가능한 암호화는 채워지지 않은 새 데이터베이스에 구현되도록 설계되었습니다. 기존 데이터베이스에 구성된 모든 비컨은 데이터베이스에 업로드된 새 레코드만 매핑하며, 비컨이 기존 데이터를 매핑할 방법은 없습니다.

**주제**
+ [비컨이 내 데이터 세트에 적합한가?](#are-beacons-right-for-me)
+ [검색 가능한 암호화 시나리오](#beacon-overview-example)

## 비컨이 내 데이터 세트에 적합한가?
<a name="are-beacons-right-for-me"></a>

비컨을 사용하여 암호화된 데이터에 대한 쿼리를 수행하면 클라이언트측 암호화된 데이터베이스와 관련된 성능 비용을 줄일 수 있습니다. 비컨을 사용할 때 쿼리의 효율성과 데이터 분포에 대해 공개되는 정보의 양 사이에는 본질적인 균형이 있습니다. 비컨은 필드의 암호화된 상태를 변경하지 않습니다. AWS Database Encryption SDK로 필드를 암호화하고 서명하면 필드의 일반 텍스트 값이 데이터베이스에 노출되지 않습니다. 데이터베이스는 필드의 무작위화되고 암호화된 값을 저장합니다.

비컨은 비컨이 계산되는 암호화된 필드와 함께 저장됩니다. 즉, 인증되지 않은 사용자가 암호화된 필드의 일반 텍스트 값을 볼 수 없더라도 비컨에 대한 통계 분석을 수행하여 데이터 세트 분포에 대해 자세히 알아보고, 극단적인 경우에는 비컨이 매핑하는 일반 텍스트 값을 식별할 수 있습니다. 비컨을 구성하는 방식으로 이러한 위험을 완화할 수 있습니다. 특히 [올바른 비컨 길이를 선택하면](choosing-beacon-length.md) 데이터 세트의 기밀을 유지하는 데 도움이 될 수 있습니다.

**보안과 성능 비교**
+ 비컨 길이가 짧을수록 보안이 더 많이 보존됩니다.
+ 비컨 길이가 길수록 성능이 더 많이 보존됩니다.

검색 가능한 암호화는 모든 데이터 세트에 대해 원하는 수준의 성능과 보안을 모두 제공하지 못할 수 있습니다. 비컨을 구성하기 전에 위협 모델, 보안 요구 사항 및 성능 요구 사항을 검토하세요.

검색 가능한 암호화가 데이터 세트에 적합한지 결정할 때 다음 데이터 세트 고유성 요구 사항을 고려하세요.

**배포**  
비컨이 보존하는 보안 수준은 데이터 세트의 배포에 따라 달라집니다. 검색 가능한 암호화를 위해 암호화된 필드를 구성하면 AWS Database Encryption SDK는 해당 필드에 기록된 일반 텍스트 값을 통해 HMAC를 계산합니다. 주어진 필드에 대해 계산된 모든 비컨은 동일한 키를 사용하여 계산됩니다. 단, 각 테넌트에 대해 고유한 키를 사용하는 멀티테넌트 데이터베이스는 예외입니다. 즉, 동일한 일반 텍스트 값을 필드에 여러 번 기록하면 해당 일반 텍스트 값의 모든 인스턴스에 대해 동일한 HMAC 태그가 생성됩니다.  
매우 일반적인 값을 포함하는 필드에서 비컨을 생성하지 않아야 합니다. 일리노이주의 모든 거주자의 주소를 저장하는 데이터베이스를 예로 들어 보겠습니다. 암호화된 `City` 필드를 기반으로 비컨을 구성하면 일리노이주 인구 중 시카고에 거주하는 인구가 많기 때문에 “시카고”를 기준으로 계산된 비컨이 과다 표시될 수 있습니다. 인증되지 않은 사용자는 암호화된 값과 비컨 값만 읽을 수 있더라도 비컨이 이 배포를 보존한다면 시카고 거주자에 대한 데이터가 들어 있는 레코드를 식별할 수 있을 것입니다. 배포에 대해 드러나는 식별 정보의 양을 최소화하려면 비컨을 충분히 잘라야 합니다. 이 고르지 않은 분포를 숨기는 데 필요한 비컨 길이로 인해 성능 비용이 많이 들기 때문에 애플리케이션의 요구 사항을 충족하지 못할 수 있습니다.  
데이터 세트의 분포를 주의 깊게 분석하여 비컨을 잘라야 하는 정도를 결정해야 합니다. 잘린 후 남은 비컨 길이는 분포에 대해 식별할 수 있는 통계 정보의 양과 직접적인 상관 관계가 있습니다. 데이터 세트에 대해 드러나는 식별 정보의 양을 충분히 최소화하려면 더 짧은 비컨 길이를 선택해야 할 수도 있습니다.  
성능과 보안의 균형을 효과적으로 유지하는 고르지 않게 분산된 데이터 집합의 비컨 길이를 계산할 수 없는 경우도 있습니다. 예를 들어, 희귀 질환에 대한 의료 검사 결과를 저장하는 필드에서 비컨을 구성해서는 안 됩니다. `NEGATIVE` 결과가 데이터셋 내에서 훨씬 더 널리 퍼질 것으로 예상되므로, `POSITIVE` 결과가 얼마나 희귀한지에 따라 결과를 쉽게 식별할 수 있습니다. 필드에 가능한 값이 두 개뿐인 경우 분포를 숨기기가 매우 어렵습니다. 분포를 숨길 만큼 짧은 비컨 길이를 사용하면 모든 일반 텍스트 값이 동일한 HMAC 태그에 매핑됩니다. 더 긴 비컨 길이를 사용하면 어떤 비컨이 일반 텍스트 `POSITIVE` 값에 매핑되는지 명확히 알 수 있습니다.

**상관관계**  
상관 관계가 있는 값을 포함한 필드에서 별개의 비컨을 생성하지 않는 것이 좋습니다. 상관 관계가 있는 필드로 구성된 비컨은 각 데이터 세트가 인증되지 않은 사용자에게 배포되는 과정에서 노출되는 정보의 양을 충분히 최소화하기 위해 비컨 길이를 줄여야 합니다. 엔트로피와 상관 관계가 있는 값의 공동 분포 등 데이터 세트를 주의 깊게 분석하여 비컨을 얼마나 잘라야 하는지 결정해야 합니다. 결과 비컨 길이가 성능 요구 사항을 충족하지 못하면 비컨이 데이터 세트에 적합하지 않을 수 있습니다.  
예를 들어 우편번호가 한 도시에만 연결될 가능성이 높으므로 `City` 및 `ZIPCode` 필드로 분리된 두 개의 비컨을 만들면 안 됩니다. 일반적으로 비컨에서 생성되는 오탐은 승인되지 않은 사용자가 데이터세트에 대한 식별 가능한 정보를 식별하는 능력을 제한합니다. 그러나 `City` 및 `ZIPCode` 필드 사이의 상관 관계를 통해 권한이 없는 사용자도 어떤 결과가 오탐인지 쉽게 식별하고 서로 다른 우편 번호를 구별할 수 있습니다.  
또한 동일한 일반 텍스트 값을 포함하는 필드에서 비컨을 구성하지 않아야 합니다. 예를 들어, 두 개의 필드는 동일한 값을 가질 가능성이 높으므로 `mobilePhone` 및 `preferredPhone` 필드에서 비컨을 생성해서는 안 됩니다. 두 필드 모두에서 고유한 비컨을 구성하는 경우 AWS Database Encryption SDK는 서로 다른 키 아래에 각 필드에 대한 비컨을 생성합니다. 그 결과 동일한 일반 텍스트 값에 대해 서로 다른 두 개의 HMAC 태그가 생성됩니다. 서로 다른 두 개의 비컨은 동일한 오탐을 가질 가능성이 낮으며, 인증되지 않은 사용자가 서로 다른 전화번호를 구별할 수도 있습니다.

데이터 세트에 상관 관계가 있는 필드가 포함되어 있거나 분포가 고르지 않은 경우에도 비컨 길이를 줄이면 데이터 세트의 기밀성을 유지하는 비컨을 구성할 수 있습니다. 하지만 비컨 길이가 데이터 세트의 모든 고유한 값이 다수의 오탐을 생성하여 데이터 세트에 대해 드러나는 식별 정보의 양을 효과적으로 최소화할 수 있다는 보장은 없습니다. 비컨 길이는 생성된 오탐의 평균 횟수만 추정합니다. 데이터 세트가 고르지 않게 분산될수록 생성되는 평균 오탐 수를 결정할 수 있는 비컨 길이의 효율성이 떨어집니다.

비컨을 구성하는 필드의 분포를 신중하게 고려하고 보안 요구 사항을 충족하기 위해 비컨 길이를 얼마나 줄여야 하는지 생각해야 합니다. 이 장의 다음 주제에서는 비컨이 균일하게 분산되어 있으며 상관 관계가 있는 데이터를 포함하지 않는다고 가정합니다.

## 검색 가능한 암호화 시나리오
<a name="beacon-overview-example"></a>

다음의 예제는 간단한 검색 가능한 암호화 솔루션을 보여줍니다. 애플리케이션에서 이 예제에 사용된 예제 필드는 비컨에 대한 배포 및 상관 관계 고유성 권장 사항을 충족하지 않을 수 있습니다. 이 장의 검색 가능한 암호화 개념에 대해 읽을 때 이 예제를 참조용으로 사용할 수 있습니다.

회사의 직원 데이터를 추적하는 `Employees`이라는 데이터베이스를 예제로 들어 보겠습니다. 데이터베이스의 각 레코드에는 *EmployeeID*, *LastName*, *FirstName*, 및 *Address*라는 필드가 포함되어 있습니다. `Employees` 데이터베이스의 각 필드는 프라이머리 키 `EmployeeID`로 식별됩니다.

다음은 데이터베이스의 일반 텍스트 레코드의 예제입니다.

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

`LastName` 및 `FirstName` 필드를 [암호화 작업](concepts.md#crypt-actions)과 같이 `ENCRYPT_AND_SIGN`으로 표시한 경우 이러한 필드의 값은 데이터베이스에 업로드되기 전에 로컬로 암호화됩니다. 업로드되는 암호화된 데이터는 완전히 무작위화되며 데이터베이스는 이 데이터를 보호 대상으로 인식하지 않습니다. 일반적인 데이터 입력만 탐지합니다. 즉, 데이터베이스에 실제로 저장되는 레코드는 다음과 같이 보일 수 있습니다.

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

데이터베이스에서 `LastName` 필드가 정확히 일치하는지 쿼리해야 하는 경우 `LastName` 필드에 기록된 일반 텍스트 값을 데이터베이스에 저장된 암호화된 값에 매핑하도록 *LastName*이라는 [표준 비컨을 구성합니다](configure-beacons.md#config-standard-beacons).

이 비컨은 `LastName` 필드의 일반 텍스트 값을 기반으로 HMAC를 계산합니다. 각 HMAC 출력은 잘려서 더 이상 일반 텍스트 값과 정확히 일치하지 않습니다. 예를 들어, `Jones`에 대한 전체 해시와 잘린 해시는 다음과 같이 보일 수 있습니다.

**전체 해시**

`2aa4e9b404c68182562b6ec761fcca5306de527826a69468885e59dc36d0c3f824bdd44cab45526f70a2a18322000264f5451acf75f9f817e2b35099d408c833`

**잘린 해시**

`b35099d408c833`

표준 비컨을 구성한 후 `LastName` 필드에서 동등 검색을 수행할 수 있습니다. 예를 들어, `Jones`에 대해 검색하려는 경우 *LastName* 비컨을 사용하여 다음 쿼리를 수행합니다.

```
LastName = Jones
```

 AWS Database Encryption SDK는 오탐을 자동으로 필터링하고 쿼리의 일반 텍스트 결과를 반환합니다.

# 비컨
<a name="beacons"></a>


****  

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

비컨은 필드에 기록된 일반 텍스트 값과 데이터베이스에 실제로 저장된 암호화된 값 사이의 맵을 생성하는 잘린 해시 기반 메시지 인증 코드(HMAC) 태그입니다. 비컨은 필드의 암호화된 상태를 변경하지 않습니다. 비컨은 필드의 일반 텍스트 값에 대한 HMAC를 계산하여 암호화된 값과 함께 저장합니다. 이 HMAC 출력은 해당 필드의 일반 텍스트 값과 일대일(1:1) 일치합니다. 여러 개의 고유한 일반 텍스트 값이 잘린 동일한 HMAC 태그에 매핑되도록 HMAC 출력이 잘립니다. 이러한 오탐은 일반 텍스트 값에 대한 구별 정보를 식별하는 권한이 없는 사용자의 능력을 제한합니다.

비컨은 [암호화 작업](concepts.md#crypt-actions)`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`에서 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`또는 로 표시된 필드로만 구성할 수 있습니다. 비컨 자체는 서명되거나 암호화되지 않습니다. `DO_NOTHING`로 표시된 필드로는 비컨을 구성할 수 없습니다.

구성하는 비컨의 유형에 따라 수행할 수 있는 쿼리 유형이 결정됩니다. 검색 가능한 암호화를 지원하는 두 가지 유형의 비컨이 있습니다. *표준 비컨*은 동등 검색을 수행합니다. *복합 비컨*은 기본적 일반 텍스트 문자열과 표준 비컨을 결합하여 복잡한 데이터베이스 작업을 수행합니다. [비컨을 구성](configure-beacons.md)한 후 암호화된 필드를 검색하려면 먼저 각 비컨에 대한 보조 인덱스를 구성해야 합니다. 자세한 내용은 [비컨을 사용한 보조 인덱스 구성](ddb-searchable-encryption.md#ddb-beacon-indexes) 단원을 참조하십시오.

**Topics**
+ [표준 비컨](#standard-beacon-overview)
+ [복합 비컨](#compound-beacon-overview)

## 표준 비컨
<a name="standard-beacon-overview"></a>

표준 비컨은 데이터베이스에서 검색 가능한 암호화를 구현하는 가장 간단한 방법입니다. 암호화된 필드 또는 가상 필드 하나에 대해서만 동등 검색을 수행할 수 있습니다. 표준 비컨을 구성하는 방법을 알아보려면 [표준 비컨 구성](configure-beacons.md#config-standard-beacons)을 참조하세요.



표준 비컨을 구성하는 필드를 *비컨 소스*라고 합니다. 비컨이 매핑해야 하는 데이터의 위치를 식별합니다. 비컨 소스는 암호화된 필드 또는 *가상 필드*일 수 있습니다. 각 표준 비컨의 비컨 소스는 고유해야 합니다. 동일한 비컨 소스로 두 개의 비컨을 구성할 수 없습니다.

표준 비컨을 사용하여 암호화된 필드 또는 가상 필드를 동등하게 검색할 수 있습니다. 또는 복합 비컨을 구성하여 더 복잡한 데이터베이스 작업을 수행하는 데 사용할 수 있습니다. 표준 비컨을 구성하고 관리하는 데 도움이 되도록 AWS Database Encryption SDK는 표준 *비컨의 용도를 정의하는 다음과 같은 선택적 비컨 스타일을* 제공합니다. 자세한 내용은 [비컨 스타일 정의를 참조하세요](configure-beacons.md#define-beacon-styles).

암호화된 단일 필드에 대해 등식 검색을 수행하는 표준 비컨을 생성하거나 가상 필드를 생성하여 여러 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`및 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 필드의 연결에 대해 등식 검색을 수행하는 표준 비컨을 생성할 수 있습니다.



**가상 필드**  
가상 필드는 하나 이상의 소스 필드로 구성된 개념적 필드입니다. 가상 필드를 생성해도 레코드에 새 필드가 기록되지는 않습니다. 가상 필드는 데이터베이스에 명시적으로 저장되지 않습니다. 표준 비컨 구성에서 필드의 특정 세그먼트를 식별하는 방법 또는 레코드 내의 여러 필드를 연결하여 특정 쿼리를 수행하는 방법에 대한 지침을 비컨에 제공하는 데 사용됩니다. 가상 필드에는 하나 이상의 암호화된 필드가 필요합니다.  
다음 예제는 가상 필드로 수행할 수 있는 변환 및 쿼리 유형을 보여줍니다. 애플리케이션에서 이 예제에 사용된 예제 필드는 비컨에 대한 [배포](searchable-encryption.md#searchable-encryption-distribution) 및 [상관 관계](searchable-encryption.md#searchable-encryption-correlated-values) 고유성 권장 사항을 충족하지 않을 수 있습니다.
예를 들어, `FirstName` 및 `LastName` 필드의 연결에 대해 동등 검색을 수행하려는 경우 다음 가상 필드 중 하나를 만들 수 있습니다.  
+ `FirstName` 필드의 첫 번째 문자와 그 뒤에 `LastName` 필드가 오는 가상 `NameTag` 필드(모두 소문자)입니다. 이 가상 필드를 사용하면 `NameTag=mjones`을 쿼리할 수 있습니다.
+ `LastName` 필드와 그 뒤에 `FirstName` 필드로 구성된 가상 `LastFirst` 필드입니다. 이 가상 필드를 사용하면 `LastFirst=JonesMary`을 쿼리할 수 있습니다.
또는 암호화된 필드의 특정 세그먼트에서 동등 검색을 수행하려는 경우 쿼리하려는 세그먼트를 식별하는 가상 필드를 만드세요.  
예를 들어 IP 주소의 처음 세 세그먼트를 사용하여 암호화된 `IPAddress` 필드를 쿼리하려면 다음 가상 필드를 만듭니다.  
+ `Segments(‘.’, 0, 3)`로 구성된 가상 `IPSegment` 필드. 이 가상 필드를 사용하면 `IPSegment=192.0.2`을 쿼리할 수 있습니다. 쿼리는 `IPAddress` 값이 “192.0.2"로 시작하는 모든 레코드를 반환합니다.
가상 필드는 고유해야 합니다. 정확히 동일한 소스 필드로 두 개의 가상 필드를 구성할 수는 없습니다.  
가상 필드 및 가상 필드를 사용하는 비컨을 구성하는 데 도움이 필요하면 [가상 필드 만들기](configure-beacons.md#create-virtual-field)를 참조하세요.

## 복합 비컨
<a name="compound-beacon-overview"></a>

복합 비컨은 쿼리 성능을 향상시키고 더 복잡한 데이터베이스 작업을 수행할 수 있도록 인덱스를 생성합니다. 복합 비컨을 사용하여 리터럴 일반 텍스트 문자열과 표준 비컨을 결합하여 암호화된 레코드에 대해 복잡한 쿼리(예: 단일 인덱스에서 서로 다른 두 레코드 유형을 쿼리하거나 정렬 키로 필드 조합을 쿼리하는 등)를 수행할 수 있습니다. 복합 비컨 솔루션 예제에 대한 자세한 내용은 [비컨 유형 선택](choosing-beacon-type.md)을 참조하세요.

복합 비컨은 표준 비컨 또는 표준 비컨과 서명된 필드의 조합으로 구성할 수 있습니다. 부분 목록으로 구성됩니다. 모든 복합 비컨에는 비컨에 포함된 `ENCRYPT_AND_SIGN` 필드를 식별하는 [암호화된 부분](configure-beacons.md#encrypted-parts) 목록이 포함되어야 합니다. 모든 `ENCRYPT_AND_SIGN` 필드는 표준 비컨으로 식별되어야 합니다. 더 복잡한 복합 비컨에는 비컨에 포함된 일반 텍스트 `SIGN_ONLY` 또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 필드를 식별하는 [서명된 부분](configure-beacons.md#signed-parts) 목록과 복합 비컨이 필드를 조합할 수 있는 가능한 모든 방법을 식별하는 [생성자 부분](configure-beacons.md#constructor-parts) 목록이 포함될 수도 있습니다.

**참고**  
 AWS Database Encryption SDK는 일반 텍스트 `SIGN_ONLY` 및 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 필드에서 완전히 구성할 수 있는 *서명된 비컨*도 지원합니다. 서명된 비컨은 서명되었지만 암호화되지 않은 필드에 대해 복잡한 쿼리를 인덱싱하고 수행하는 복합 비컨의 한 유형입니다. 자세한 내용은 [서명된 비컨 만들기](configure.md#signed-beacons) 단원을 참조하십시오.

복합 비컨 구성에 대한 도움말은 [복합 비콘 구성](configure-beacons.md#config-compound-beacons)을 참조하세요.

복합 비컨을 구성하는 방식에 따라 수행할 수 있는 쿼리 유형이 결정됩니다. 예를 들어, 일부 암호화되고 서명된 부분을 선택 사항으로 설정하여 쿼리의 유연성을 높일 수 있습니다. 복합 비컨이 수행할 수 있는 쿼리 유형에 대한 자세한 내용은 [비컨 쿼리](using-beacons.md#querying-beacons) 섹션을 참조하세요.

# 비컨 계획 수립
<a name="plan-searchable-encryption"></a>


****  

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

비컨은 채워지지 않은 새 데이터베이스에 구현되도록 설계되었습니다. 기존 데이터베이스에 구성된 모든 비컨은 데이터베이스에 기록된 새 레코드만 매핑합니다. 비컨은 필드의 일반 텍스트 값에서 계산됩니다. 필드가 암호화되면 비컨이 기존 데이터를 매핑할 방법이 없습니다. 비컨으로 새 레코드를 작성한 후에는 비컨의 구성을 업데이트할 수 없습니다. 하지만 레코드에 추가하는 새 필드에 대해 새 비컨을 추가할 수 있습니다.

검색 가능한 암호화를 구현하려면 [AWS KMS 계층 키링](use-hierarchical-keyring.md)을 사용하여 레코드 보호에 사용되는 데이터 키를 생성, 암호화 및 복호화해야 합니다. 자세한 내용은 [검색 가능한 암호화를 위한 계층적 키링 사용](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings) 단원을 참조하십시오.

검색 가능한 암호화를 위한 [비컨](searchable-encryption.md#beacon-definition)을 구성하려면 먼저 암호화 요구 사항, 데이터베이스 액세스 패턴 및 위협 모델을 검토하여 데이터베이스에 가장 적합한 솔루션을 결정해야 합니다.

구성하는 [비컨 유형](beacons.md)에 따라 수행할 수 있는 쿼리 유형이 결정됩니다. 표준 비컨 구성에서 지정하는 [비컨 길이](choosing-beacon-length.md)에 따라 해당 비컨에 대해 생성되는 예상 오탐 수가 결정됩니다. 비컨을 구성하기 전에 수행해야 하는 쿼리 유형을 식별하고 계획하는 것이 좋습니다. 비컨을 사용한 후에는 구성을 업데이트할 수 없습니다.

비컨을 구성하기 전에 다음 작업을 검토하고 완료하는 것이 좋습니다.
+ [비컨이 데이터 세트에 적합한지 판단](searchable-encryption.md#are-beacons-right-for-me)
+ [비컨 유형 선택](choosing-beacon-type.md)
+ [비컨 길이 선택](choosing-beacon-length.md)
+ [비컨 이름 선택](choosing-beacon-name.md)

데이터베이스의 검색 가능한 암호화 솔루션을 계획할 때 다음 비컨 고유성 요구 사항을 기억합니다.
+ **[모든 표준 비컨에는 고유한 비컨 소스가 있어야 합니다.](beacons.md#beacon-source)**

  동일한 암호화된 필드나 가상 필드에서 여러 표준 비컨을 구성할 수 없습니다.

  하지만 단일 표준 비컨을 사용하여 여러 복합 비컨을 구성할 수 있습니다.
+ **소스 필드가 기존 표준 비컨과 겹치는 가상 필드를 만들지 마세요.**

  다른 표준 비컨을 만드는 데 사용된 소스 필드가 포함된 가상 필드에서 표준 비컨을 구성하면 두 비컨의 보안이 저하될 수 있습니다.

  자세한 내용은 [가상 필드에 대한 보안 고려 사항](configure-beacons.md#virtual-field-considerations) 단원을 참조하십시오.

## 멀티테넌트 데이터베이스 고려 사항
<a name="planning-multitenant-beacons"></a>

멀티테넌트 데이터베이스에 구성된 비컨을 쿼리하려면 레코드를 암호화한 테넌트와 관련된 `branch-key-id`을 쿼리에 저장하는 필드를 포함해야 합니다. [비컨 키 소스를 정의](use-hierarchical-keyring.md#beacon-key-source)할 때 이 필드를 정의합니다. 쿼리가 성공하려면 이 필드의 값이 비컨을 재계산하는 데 필요한 적절한 비컨 키 자료를 식별해야 합니다.

비컨을 구성하기 전에 쿼리의 `branch-key-id`에 비컨을 어떻게 포함할지 결정해야 합니다. 쿼리에 `branch-key-id`을 포함할 수 있는 다양한 방법에 대한 자세한 내용은 [멀티테넌트 데이터베이스의 비컨 쿼리](searchable-encryption-multitenant.md#query-multitenant-beacons) 섹션을 참조하세요.

# 비컨 유형 선택
<a name="choosing-beacon-type"></a>


****  

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

검색 가능한 암호화를 사용하면 암호화된 필드의 일반 텍스트 값을 *비컨*으로 매핑하여 암호화된 레코드를 검색할 수 있습니다. 구성하는 비컨 유형에 따라 수행할 수 있는 쿼리 유형이 결정됩니다.

비컨을 구성하기 전에 수행해야 하는 쿼리 유형을 식별하고 계획하는 것이 좋습니다. [비컨을 구성](configure-beacons.md)한 후 암호화된 필드를 검색하려면 먼저 각 비컨에 대한 보조 인덱스를 구성해야 합니다. 자세한 내용은 [비컨을 사용한 보조 인덱스 구성](ddb-searchable-encryption.md#ddb-beacon-indexes) 단원을 참조하십시오.

비컨은 필드에 기록된 일반 텍스트 값과 데이터베이스에 실제로 저장된 암호화된 값 사이의 맵을 만듭니다. 두 표준 비컨에 동일한 기본 일반 텍스트가 포함되어 있더라도 두 표준 비컨의 값을 비교할 수는 없습니다. 두 개의 표준 비컨은 동일한 일반 텍스트 값에 대해 서로 다른 두 개의 HMAC 태그를 생성합니다. 따라서 표준 비컨은 다음 쿼리를 수행할 수 없습니다.
+ `beacon1 = beacon2`
+ `beacon1 IN (beacon2)`
+ `value IN (beacon1, beacon2, ...)`
+ `CONTAINS(beacon1, beacon2)`

복합 비컨의 [서명된 부분](configure-beacons.md#signed-parts)을 비교하는 경우에만 위의 쿼리를 수행할 수 있습니다. 단, 복합 비컨과 함께 사용하여 조합된 비컨에 포함된 암호화되거나 서명된 필드의 전체 값을 식별할 수 있는 `CONTAINS` 연산자는 예외입니다. 서명된 부분을 비교할 때 선택적으로 [암호화된 부분](configure-beacons.md#encrypted-parts)의 접두사를 포함할 수 있지만 필드의 암호화된 값은 포함할 수 없습니다. 표준 및 복합 비컨이 수행할 수 있는 쿼리 유형에 대한 자세한 내용은 [비컨 쿼리](using-beacons.md#querying-beacons)를 참조하세요.

데이터베이스 액세스 패턴을 검토할 때 다음과 같은 검색 가능한 암호화 솔루션을 고려하세요. 다음 예제는 다양한 암호화 및 쿼리 요구 사항을 충족하도록 구성할 비컨을 정의합니다.

## 표준 비컨
<a name="plan-standard-beacon"></a>

[표준 비컨](beacons.md#standard-beacon-overview)은 평등 검색만 수행할 수 있습니다. 표준 비컨을 사용하여 다음 쿼리를 수행할 수 있습니다.

### 암호화된 단일 필드 쿼리
<a name="se-example1"></a>

암호화된 필드의 특정 값이 포함된 레코드를 식별하려면 표준 비컨을 만드세요.

#### 예제
<a name="example1"></a>

다음 예제에서는 프로덕션 시설에 대한 검사 데이터를 추적하는 `UnitInspection`라는 이름의 데이터베이스를 고려합니다. 데이터베이스의 각 레코드에는 `work_id`, `inspection_date`, `inspector_id_last4`, 및 `unit`라는 필드가 있습니다. 전체 검사기 ID는 0\$199,999,999 사이의 숫자입니다. 하지만 데이터세트가 균일하게 분포되도록 하기 위해 `inspector_id_last4`에는 검사기 ID의 마지막 4자리만 저장됩니다. 데이터베이스의 각 필드는 프라이머리 키 `work_id`로 식별됩니다. `inspector_id_last4` 및 `unit` 필드는 [암호화 작업](concepts.md#crypt-actions)에서 `ENCRYPT_AND_SIGN`으로 표시됩니다.

다음은 `UnitInspection` 데이터베이스의 일반 텍스트 항목의 예입니다.

```
{
    "work_id": "1c7fcff3-6e74-41a8-b7f7-925dc039830b",
    "inspection_date": 2023-06-07,
    "inspector_id_last4": 8744,
    "unit": 229304973450   
}
```

**레코드의 단일 암호화된 필드 쿼리**  
`inspector_id_last4` 필드를 암호화해야 하지만 정확히 일치하는지 쿼리해야 하는 경우 `inspector_id_last4` 필드에서 표준 비컨을 생성합니다. 그런 다음 표준 비컨을 사용하여 보조 인덱스를 만듭니다. 이 보조 인덱스를 사용하여 암호화된 `inspector_id_last4` 필드를 쿼리할 수 있습니다.

표준 비컨 구성에 대한 도움말은 [표준 비컨 구성](configure-beacons.md#config-standard-beacons)을 참조하세요.

### 가상 필드 쿼리
<a name="se-example2"></a>

[가상 필드](beacons.md#virtual-field)는 하나 이상의 소스 필드로 구성된 개념적 필드입니다. 암호화된 필드의 특정 세그먼트에 대해 동등 검색을 수행하거나 여러 필드의 연결에 대해 동등 검색을 수행하려면 가상 필드에서 표준 비컨을 구성합니다. 모든 가상 필드는 하나 이상의 암호화된 소스 필드를 포함해야 합니다.

#### 예제
<a name="example2"></a>

다음 예제는 `Employees` 데이터베이스의 가상 필드를 만듭니다. 다음은 `Employees` 데이터베이스의 일반 텍스트 레코드의 예제입니다.

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

**암호화된 필드의 세그먼트 쿼리**  
이 예제에서는 `SSN` 필드가 암호화됩니다.  
사회보장번호의 마지막 4자리를 사용하여 `SSN` 필드를 쿼리하려면 쿼리하려는 세그먼트를 식별하는 가상 필드를 만드십시오.  
`Last4SSN`로 구성된 가상 `Suffix(4)` 필드를 사용하면 `Last4SSN=0000`를 쿼리할 수 있습니다. 이 가상 필드를 사용하여 표준 비컨을 구성합니다. 그런 다음 표준 비컨을 사용하여 보조 인덱스를 만듭니다. 이 보조 인덱스를 사용하여 가상 필드를 쿼리할 수 있습니다. 이 쿼리는 지정한 마지막 4자리 숫자로 끝나는 `SSN` 값을 가진 모든 레코드를 반환합니다.

**여러 필드의 연결 쿼리**  
다음 예제는 가상 필드로 수행할 수 있는 변환 및 쿼리 유형을 보여줍니다. 애플리케이션에서 이 예제에 사용된 예제 필드는 비컨에 대한 [배포](searchable-encryption.md#searchable-encryption-distribution) 및 [상관 관계](searchable-encryption.md#searchable-encryption-correlated-values) 고유성 권장 사항을 충족하지 않을 수 있습니다.
`FirstName` 및 `LastName` 필드 연결에 대해 동일 검색을 수행하려는 경우 `FirstName` 필드의 첫 번째 문자와 그 뒤에 오는 `LastName` 필드(모두 소문자)로 구성되는 가상 `NameTag` 필드를 생성할 수 있습니다. 이 가상 필드를 사용하여 표준 비컨을 구성합니다. 그런 다음 표준 비컨을 사용하여 보조 인덱스를 만듭니다. 이 보조 인덱스를 사용하여 가상 필드에 대한 `NameTag=mjones`를 쿼리할 수 있습니다.  
원본 필드 중 하나 이상을 암호화해야 합니다. `FirstName` 또는 `LastName` 둘 중 하나를 암호화하거나 둘 다 암호화할 수 있습니다. 모든 일반 텍스트 소스 필드는 [암호화 작업](concepts.md#crypt-actions)`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`에서 `SIGN_ONLY` 또는 로 표시되어야 합니다.

가상 필드 및 가상 필드를 사용하는 비컨을 구성하는 데 도움이 필요하면 [가상 필드 만들기](configure-beacons.md#create-virtual-field)를 참조하세요.

## 복합 비컨
<a name="plan-compound-beacons"></a>

[복합 비컨](beacons.md#compound-beacon-overview)은 기본적 일반 텍스트 문자열과 표준 비컨에서 인덱스를 생성하여 복잡한 데이터베이스 작업을 수행합니다. 복합 비컨을 사용하여 다음 쿼리를 수행할 수 있습니다.

### 단일 인덱스에서 암호화된 필드 조합 쿼리
<a name="se-example3"></a>

단일 인덱스에서 암호화된 필드 조합을 쿼리해야 하는 경우, 암호화된 각 필드에 대해 구성된 개별 표준 비컨을 결합하여 단일 인덱스를 형성하는 복합 비컨을 만듭니다.

복합 비컨을 구성한 후에는 복합 비컨을 파티션 키로 지정하여 정확히 일치 쿼리를 수행하거나 정렬 키를 사용하여 더 복잡한 쿼리를 수행하는 보조 인덱스를 만들 수 있습니다. 복합 비컨을 정렬 키로 지정하는 보조 인덱스는 정확히 일치하는 쿼리와 보다 맞춤화된 복합 쿼리를 수행할 수 있습니다.

#### 예제
<a name="example3"></a>

다음 예제에서는 프로덕션 시설에 대한 검사 데이터를 추적하는 `UnitInspection`라는 이름의 데이터베이스를 고려합니다. 데이터베이스의 각 레코드에는 `work_id`, `inspection_date`, `inspector_id_last4`, 및 `unit`라는 필드가 있습니다. 전체 검사기 ID는 0\$199,999,999 사이의 숫자입니다. 하지만 데이터세트가 균일하게 분포되도록 하기 위해 `inspector_id_last4`에는 검사기 ID의 마지막 4자리만 저장됩니다. 데이터베이스의 각 필드는 프라이머리 키 `work_id`로 식별됩니다. `inspector_id_last4` 및 `unit` 필드는 [암호화 작업](concepts.md#crypt-actions)에서 `ENCRYPT_AND_SIGN`으로 표시됩니다.

다음은 `UnitInspection` 데이터베이스의 일반 텍스트 항목의 예입니다.

```
{
    "work_id": "1c7fcff3-6e74-41a8-b7f7-925dc039830b",
    "inspection_date": 2023-06-07,
    "inspector_id_last4": 8744,
    "unit": 229304973450
}
```

**암호화된 필드 조합에서 동등 검색 수행**  
`inspector_id_last4.unit`에서 정확히 일치하는 항목을 `UnitInspection` 데이터베이스에 쿼리하려면 먼저 `inspector_id_last4` 및 `unit` 필드에 대해 고유한 표준 비컨을 만듭니다. 그런 다음 두 개의 표준 비컨으로 복합 비컨을 만듭니다.  
복합 비컨을 구성한 후 복합 비컨을 파티션 키로 지정하는 보조 인덱스를 만듭니다. 이 보조 인덱스를 사용하여 `inspector_id_last4.unit`에 대해 정확히 일치하는 항목을 쿼리할 수 있습니다. 예를 들어, 이 비컨을 쿼리하여 검사기가 특정 단위에 대해 수행한 검사 목록을 찾을 수 있습니다.

**암호화된 필드 조합에 대해 복잡한 쿼리 수행**  
`inspector_id_last4` 및 `inspector_id_last4.unit`에서 `UnitInspection` 데이터베이스를 쿼리하려면 먼저 `inspector_id_last4` 및 `unit` 필드에 대해 고유한 표준 비컨을 만듭니다. 그런 다음 두 개의 표준 비컨으로 복합 비컨을 만듭니다.  
복합 비컨를 구성한 후 복합 비컨을 정렬 키로 지정하는 보조 인덱스를 만듭니다. 이 보조 인덱스를 사용하여 특정 검사기로 시작하는 항목을 `UnitInspection` 데이터베이스에 쿼리하거나 특정 검사기에서 검사한 특정 장치 ID 범위 내의 모든 장치 목록을 데이터베이스에 쿼리할 수 있습니다. `inspector_id_last4.unit`에서 정확히 일치하는 검색을 수행할 수도 있습니다.

복합 비컨 구성에 대한 도움말은 [복합 비콘 구성](configure-beacons.md#config-compound-beacons)을 참조하세요.

### 단일 인덱스에서 암호화된 필드와 일반 텍스트 필드의 조합 쿼리
<a name="se-example4"></a>

단일 인덱스에서 암호화된 필드와 일반 텍스트 필드를 조합하여 쿼리해야 하는 경우 개별 표준 비컨과 일반 텍스트 필드를 결합하여 단일 인덱스를 형성하는 복합 비컨을 만듭니다. 복합 비컨을 구성하는 데 사용되는 일반 텍스트 필드는 [암호화 작업](concepts.md#crypt-actions)`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`에서 `SIGN_ONLY` 또는 로 표시되어야 합니다.

복합 비컨을 구성한 후에는 복합 비컨을 파티션 키로 지정하여 정확히 일치 쿼리를 수행하거나 정렬 키를 사용하여 더 복잡한 쿼리를 수행하는 보조 인덱스를 만들 수 있습니다. 복합 비컨을 정렬 키로 지정하는 보조 인덱스는 정확히 일치하는 쿼리와 보다 맞춤화된 복합 쿼리를 수행할 수 있습니다.

#### 예제
<a name="example4"></a>

다음 예제에서는 프로덕션 시설에 대한 검사 데이터를 추적하는 `UnitInspection`라는 이름의 데이터베이스를 고려합니다. 데이터베이스의 각 레코드에는 `work_id`, `inspection_date`, `inspector_id_last4`, 및 `unit`라는 필드가 있습니다. 전체 검사기 ID는 0\$199,999,999 사이의 숫자입니다. 하지만 데이터세트가 균일하게 분포되도록 하기 위해 `inspector_id_last4`에는 검사기 ID의 마지막 4자리만 저장됩니다. 데이터베이스의 각 필드는 프라이머리 키 `work_id`로 식별됩니다. `inspector_id_last4` 및 `unit` 필드는 [암호화 작업](concepts.md#crypt-actions)에서 `ENCRYPT_AND_SIGN`으로 표시됩니다.

다음은 `UnitInspection` 데이터베이스의 일반 텍스트 항목의 예입니다.

```
{
    "work_id": "1c7fcff3-6e74-41a8-b7f7-925dc039830b",
    "inspection_date": 2023-06-07,
    "inspector_id_last4": 8744,
    "unit": 229304973450
}
```

**필드 조합에서 동등 검색 수행**  
특정 검사관이 특정 날짜에 실시한 검사에 대해 `UnitInspection` 데이터베이스를 쿼리하려면 먼저 `inspector_id_last4` 필드에 대한 표준 비컨을 만듭니다. 이 `inspector_id_last4` 필드는 [암호화 작업](concepts.md#crypt-actions)에 `ENCRYPT_AND_SIGN`로 표시됩니다. 암호화된 모든 부분에는 자체 표준 비컨이 필요합니다. `inspection_date` 필드는 `SIGN_ONLY`로 표시가 되어 있으며 표준 비컨이 필요하지 않습니다. 다음으로, `inspection_date` 필드와 `inspector_id_last4` 표준 비컨에서 복합 비컨을 만듭니다.  
복합 비컨을 구성한 후 복합 비컨을 파티션 키로 지정하는 보조 인덱스를 만듭니다. 이 보조 인덱스를 사용하여 데이터베이스에서 특정 검사기 및 검사 날짜와 정확히 일치하는 레코드를 쿼리할 수 있습니다. 예를 들어, ID가 `8744`로 끝나는 검사기가 특정 날짜에 실시한 모든 검사 목록을 데이터베이스에 쿼리할 수 있습니다.

**필드 조합에 대해 복잡한 쿼리 수행**  
`inspection_date` 범위 내에서 수행된 검사에 대해 데이터베이스를 쿼리하거나 `inspector_id_last4` 또는 `inspector_id_last4.unit`로 제한된 특정 `inspection_date`에서 수행된 검사에 대해 데이터베이스를 쿼리하려면 먼저 `inspector_id_last4` 및 `unit` 필드에 대해 별도의 표준 비컨을 생성합니다. 그런 다음 일반 텍스트 `inspection_date` 필드와 두 개의 표준 비컨을 사용하여 복합 비컨을 만듭니다.  
복합 비컨를 구성한 후 복합 비컨을 정렬 키로 지정하는 보조 인덱스를 만듭니다. 이 보조 인덱스를 사용하여 특정 검사기가 특정 날짜에 실시한 검사에 대한 쿼리를 수행할 수 있습니다. 예를 들어 같은 날짜에 검사한 모든 단위의 목록을 데이터베이스에 쿼리할 수 있습니다. 또는 지정된 검사 날짜 범위 사이에 특정 단위에 대해 수행된 모든 검사 목록을 데이터베이스에 쿼리할 수 있습니다.

복합 비컨 구성에 대한 도움말은 [복합 비콘 구성](configure-beacons.md#config-compound-beacons)을 참조하세요.

# 비컨 길이 선택
<a name="choosing-beacon-length"></a>


****  

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

검색 가능한 암호화를 위해 구성된 암호화된 필드에 새 값을 작성하면 AWS Database Encryption SDK가 일반 텍스트 값을 통해 HMAC를 계산합니다. 이 HMAC 출력은 해당 필드의 일반 텍스트 값과 일대일(1:1) 일치합니다. 여러 개의 고유한 일반 텍스트 값이 잘린 동일한 HMAC 태그에 매핑되도록 HMAC 출력이 잘립니다. 이러한 충돌 또는 *오탐*은 일반 텍스트 값에 대한 구별 정보를 식별하는 권한이 없는 사용자의 능력을 제한합니다.

각 비컨에 대해 생성된 평균 오탐 수는 잘린 후 남은 비컨 길이에 따라 결정됩니다. 표준 비컨을 구성할 때 비컨 길이만 정의하면 됩니다. 복합 비컨은 구성된 표준 비컨의 비컨 길이를 사용합니다.

비컨은 필드의 암호화된 상태를 변경하지 않습니다. 그러나 비컨을 사용할 때 쿼리의 효율성과 데이터 분포에 대해 공개되는 정보의 양 사이에는 본질적인 균형이 있습니다.

검색 가능한 암호화의 목표는 비컨을 사용하여 암호화된 데이터에 대한 쿼리를 수행함으로써 클라이언트측 암호화된 데이터베이스와 관련된 성능 비용을 줄이는 것입니다. 비컨은 비컨이 계산되는 암호화된 필드와 함께 저장됩니다. 이는 데이터 세트의 분포에 대한 구별되는 정보를 공개할 수 있음을 의미합니다. 극단적인 경우 권한이 없는 사용자가 배포에 대해 공개된 정보를 분석하고 이를 사용하여 필드의 일반 텍스트 값을 식별할 수 있습니다. 올바른 비컨 길이를 선택하면 이러한 위험을 완화하고 배포의 기밀성을 유지하는 데 도움이 될 수 있습니다.

위협 모델을 검토하여 필요한 보안 수준을 결정합니다. 예를 들어, 데이터베이스에 액세스할 수 있지만 일반 텍스트 데이터에 액세스할 수 없는 개인이 많을수록 데이터 세트 배포의 기밀성을 더 많이 보호해야 할 수 있습니다. 기밀성을 높이려면 비컨이 더 많은 오탐을 생성해야 합니다. 기밀성이 높아지면 쿼리 성능이 저하됩니다.

**보안과 성능 비교**
+ 비컨 길이가 **너무 길면** 오탐이 너무 적어 데이터 세트 분포에 대한 구별 정보가 공개될 수 있습니다.
+ 비컨 길이가 **너무 짧으면** 오탐이 너무 많이 발생하고 데이터베이스를 더 광범위하게 검색해야 하므로 쿼리 성능 비용이 증가합니다.

솔루션에 적합한 비컨 길이를 결정할 때 꼭 필요한 것 이상으로 쿼리 성능에 영향을 주지 않고 데이터 보안을 적절하게 유지하는 길이를 찾아야 합니다. 비컨에 의해 유지되는 보안 수준은 데이터 세트의 [분포](searchable-encryption.md#searchable-encryption-distribution)와 비컨이 구성된 필드의 [상관 관계](searchable-encryption.md#searchable-encryption-correlated-values)에 따라 달라집니다. 다음 주제에서는 비컨이 균일하게 분포되어 있고 상관된 데이터를 포함하지 않는다고 가정합니다.

**Topics**
+ [비컨 길이 계산](#calculate-beacon-length)
+ [예제](#beacon-length-example)

## 비컨 길이 계산
<a name="calculate-beacon-length"></a>

비컨 길이는 *비트* 단위로 정의되며 잘린 후에도 유지되는 HMAC 태그의 비트 수를 나타냅니다. 권장되는 비컨 길이는 데이터 세트 분포, 상관 값의 존재, 특정 보안 및 성능 요구 사항에 따라 다릅니다. 데이터 세트가 균일하게 분포된 경우 다음 방정식과 절차를 사용하여 구현에 가장 적합한 비컨 길이를 식별하는 데 도움이 될 수 있습니다. 이러한 방정식은 비컨이 생성할 평균 오탐 수만 추정할 뿐 데이터 세트의 모든 고유 값이 특정 개수의 오탐을 생성한다고 보장하지는 않습니다.

**참고**  
이러한 방정식의 효율성은 데이터 세트의 분포에 따라 달라집니다. 데이터세트가 균일하게 분포되지 않은 경우 [비컨이 내 데이터 세트에 적합한가?](searchable-encryption.md#are-beacons-right-for-me) 섹션을 참조하세요.  
일반적으로 데이터 세트가 균일한 분포에서 멀어질수록 비컨 길이를 더 줄여야 합니다.

1. 

   **모집단 추정**

   모집단은 표준 비컨을 구성하는 필드의 예상 고유 값 수이며, 필드에 저장된 총 예상 값 수가 아닙니다. 예를 들어 직원 회의 위치를 식별하는 암호화된 `Room` 필드를 고려하세요. `Room` 필드에는 총 100,000개의 값이 저장될 것으로 예상되지만 직원이 회의를 위해 예약할 수 있는 공간은 50개뿐입니다. 즉, `Room` 필드에 저장할 수 있는 고유 값은 50개뿐이므로 모집단은 50개입니다.
**참고**  
표준 비컨이 [가상 필드](beacons.md#virtual-field)에서 구성된 경우 비컨 길이를 계산하는 데 사용되는 인구는 가상 필드에서 생성된 고유 조합의 수입니다.

   모집단을 추정할 때 데이터 세트의 예상 증가를 고려해야 합니다. 비컨으로 새 레코드를 작성한 후에는 비컨 길이를 업데이트할 수 없습니다. 위협 모델과 기존 데이터베이스 솔루션을 검토하여 향후 5년 동안 이 필드에 저장할 것으로 예상되는 고유 값의 수에 대한 추정치를 생성합니다.

   모집단은 정확할 필요는 없습니다. 먼저, 현재 데이터베이스의 고유 값 수를 식별하거나 첫 해에 저장할 것으로 예상되는 고유 값 수를 추정합니다. 다음으로, 다음 질문을 사용하여 향후 5년 동안 고유한 가치의 예상 성장을 결정하는 데 도움을 받으세요.
   + 고유한 값에 10이 곱해질 것이라고 예상하시나요?
   + 고유한 값에 100이 곱해질 것이라고 예상하시나요?
   + 고유한 값에 1000이 곱해질 것이라고 예상하시나요?

   50,000개와 60,000개의 고유 값 사이의 차이는 중요하지 않으며 둘 다 동일한 권장 비컨 길이가 됩니다. 그러나 50,000과 500,000의 고유 값 사이의 차이는 권장 비컨 길이에 큰 영향을 미칩니다.

   우편번호나 성 등 일반적인 데이터 유형의 빈도에 대한 공개 데이터를 검토하는 것이 좋습니다. 예를 들어, 미국에는 41,707개의 우편번호가 있습니다. 사용하는 모집단은 자신의 데이터베이스에 비례해야 합니다. 데이터베이스의 `ZIPCode` 필드에 미국 전역의 데이터가 포함되어 있는 경우 `ZIPCode` 필드에 *현재* 41,707개의 고유 값이 없더라도 모집단을 41,707로 정의할 수 있습니다. 데이터베이스의 `ZIPCode` 필드에 단일 주의 데이터만 포함되고 향후에도 단일 주의 데이터만을 포함하는 경우 모집단을 41,704가 아닌 해당 주의 총 우편 번호 수로 정의할 수 있습니다.

1. **예상 충돌 횟수에 대한 권장 범위 계산**

   특정 필드에 대한 적절한 비컨 길이를 결정하려면 먼저 예상되는 충돌 횟수에 대한 적절한 범위를 식별해야 합니다. 예상 충돌 수는 특정 HMAC 태그에 매핑되는 고유 일반 텍스트 값의 평균 예상 수를 나타냅니다. 하나의 고유한 일반 텍스트 값에 대해 예상되는 오탐 수는 예상되는 충돌 수보다 1이 적습니다.

   예상되는 충돌 횟수는 2보다 크거나 같고 인구의 제곱근보다 작은 것이 좋습니다. 다음 방정식은 모집단에 16개 이상의 고유 값이 있는 경우에만 작동합니다.

   ```
   2 ≤ number of collisions < √(Population)
   ```

   충돌 횟수가 2회 미만이면 비컨은 너무 적은 양의 오탐을 생성합니다. 평균적으로 필드의 모든 고유 값이 하나의 다른 고유 값에 매핑되어 최소한 하나의 오탐을 생성한다는 의미이므로 예상되는 최소 충돌 수로 2를 권장합니다.

1. **비컨 길이에 대한 권장 범위 계산**

   예상되는 충돌의 최소 및 최대 횟수를 식별한 후 다음 방정식을 사용하여 적절한 비컨 길이의 범위를 식별합니다.

   ```
   number of collisions = Population * 2-(beacon length)
   ```

   먼저, 예상 충돌 횟수가 2(예상 충돌의 최소 권장 횟수)인 **비컨 길이**를 구합니다.

   ```
   2 = Population * 2-(beacon length)
   ```

   그런 다음 예상되는 충돌 횟수가 모집단의 제곱근(예상되는 최대 권장 충돌 횟수)과 동일한 **비컨 길이**를 구합니다.

   ```
   √(Population) = Population * 2-(beacon length)
   ```

   이 방정식으로 생성된 출력을 더 짧은 비컨 길이로 반내림하는 것이 좋습니다. 예를 들어 방정식이 15.6의 비컨 길이를 생성하는 경우 해당 값을 16비트로 반올림하는 대신 15비트로 반내림하는 것이 좋습니다.

1. **비컨 길이 선택**

   이 방정식은 해당 분야에 권장되는 비컨 길이 범위만 식별합니다. 가능하면 데이터 세트의 보안을 유지하기 위해 더 짧은 비컨 길이를 사용하는 것이 좋습니다. 그러나 실제로 사용하는 비컨 길이는 위협 모델에 따라 결정됩니다. 해당 분야에 가장 적합한 비컨 길이를 결정하기 위해 위협 모델을 검토할 때 성능 요구 사항을 고려하세요.

   더 짧은 비컨 길이를 사용하면 쿼리 성능이 저하되고, 더 긴 비컨 길이를 사용하면 보안이 저하됩니다. 일반적으로 데이터 세트가 고르지 않게 [분포되어](searchable-encryption.md#searchable-encryption-distribution) 있거나 [상관된](searchable-encryption.md#searchable-encryption-correlated-values) 필드에서 별도의 비컨을 구성하는 경우 더 짧은 비컨 길이를 사용하여 데이터 세트 분포에 대해 공개되는 정보의 양을 최소화해야 합니다.

   위협 모델을 검토하고 필드 분포에 대해 밝혀진 구별 정보가 전체 보안에 위협이 되지 않는다고 판단하는 경우 계산한 권장 범위보다 긴 비컨 길이를 사용하도록 선택할 수 있습니다. 예를 들어, 필드에 대한 권장 비컨 길이 범위를 9\$116비트로 계산한 경우 성능 손실을 방지하기 위해 24비트의 비컨 길이를 사용하도록 선택할 수 있습니다.

   비컨 길이를 신중하게 선택하세요. 비컨으로 새 레코드를 작성한 후에는 비컨 길이를 업데이트할 수 없습니다.

## 예제
<a name="beacon-length-example"></a>

`unit` 필드를 [암호화 작업](concepts.md#crypt-actions)의 `ENCRYPT_AND_SIGN`로 표시한 데이터베이스를 고려하세요. `unit` 필드에 대한 표준 비컨을 구성하려면 `unit` 필드에 대한 예상 오탐 수와 비컨 길이를 결정해야 합니다.

1. 모집단 추정

   위협 모델과 현재 데이터베이스 솔루션을 검토한 결과 `unit` 필드는 결국 100,000개의 고유 값을 갖게 될 것으로 예상됩니다.

   이는 **모집단 = 100,000**을 의미합니다.

1. 예상 충돌 횟수에 대한 권장 범위 계산.

   이 예제에서 예상되는 충돌 횟수는 2\$1316 사이여야 합니다.

   ```
   2 ≤ number of collisions < √(Population)
   ```

   1. 

      ```
      2 ≤ number of collisions < √(100,000)
      ```

   1. 

      ```
      2 ≤ number of collisions < 316
      ```

1. 비컨 길이에 대한 권장 범위를 계산합니다.

   이 예제에서 비컨 길이는 9\$116비트 사이여야 합니다.

   ```
   number of collisions = Population * 2-(beacon length)
   ```

   1. 예상되는 충돌 횟수가 **2단계**에서 식별된 최소 횟수와 동일한 비컨 길이를 계산합니다.

      ```
      2 = 100,000 * 2-(beacon length)
      ```

      비컨 길이 = 15.6 또는 15비트

   1. 예상되는 충돌 횟수가 **2단계**에서 식별된 최대 횟수와 동일한 비컨 길이를 계산합니다.

      ```
      316 = 100,000 * 2-(beacon length)
      ```

      비컨 길이 = 8.3 또는 8비트

1. 보안 및 성능 요구 사항에 적합한 비컨 길이를 결정합니다.

   15개 미만의 비트마다 성능 비용과 보안이 두 배로 늘어납니다.
   + 16비트
     + 평균적으로 각 고유 값은 1.5개의 다른 단위에 매핑됩니다.
     + 보안: 잘린 HMAC 태그가 동일한 두 레코드는 동일한 일반 텍스트 값을 가질 가능성이 66%입니다.
     + 성능: 쿼리는 실제로 요청한 레코드 10개마다 레코드 15개를 검색합니다.
   + 14비트
     + 평균적으로 각 고유 값은 6.1개의 다른 단위에 매핑됩니다.
     + 보안: 잘린 HMAC 태그가 동일한 두 레코드는 동일한 일반 텍스트 값을 가질 가능성이 33%입니다.
     + 성능: 쿼리는 실제로 요청한 레코드 30개마다 레코드 10개를 검색합니다.

# 비컨 이름 선택
<a name="choosing-beacon-name"></a>


****  

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

모든 비컨은 고유한 *비컨 이름*으로 식별됩니다. 비컨이 구성되면 암호화된 필드를 쿼리할 때 사용하는 이름이 비컨 이름이 됩니다. 비컨 이름은 암호화된 필드 또는 [가상 필드](beacons.md#virtual-field)와 같은 이름일 수 있지만 암호화되지 않은 필드와 같은 이름일 수는 없습니다. 서로 다른 두 비컨은 동일한 비컨 이름을 가질 수 없습니다.

비컨의 이름을 지정하고 구성하는 방법을 보여주는 예제는 [비컨 구성](configure-beacons.md)을 참조하세요.



**표준 비컨 이름 지정**  
표준 비컨의 이름을 지정할 때는 가능하면 비컨 이름을 [*비컨 소스*](beacons.md#beacon-source)로 확인하는 것이 좋습니다. 즉, 표준 비컨을 구성하는 데 사용되는 암호화된 필드 또는 [가상](beacons.md#virtual-field) 필드의 이름과 비컨 이름은 동일합니다. 예를 들어 `LastName`라는 이름의 암호화된 필드에 대한 표준 비컨을 만드는 경우 비컨 이름도 `LastName`이 되어야 합니다.

비컨 이름이 비컨 소스와 동일한 경우 구성에서 비컨 소스를 생략할 수 있으며 AWS Database Encryption SDK는 비컨 이름을 비컨 소스로 자동으로 사용합니다.

# 비컨 구성
<a name="configure-beacons"></a>


****  

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

검색 가능한 암호화를 지원하는 두 가지 유형의 비컨이 있습니다. 표준 비컨은 동등 검색을 수행합니다. 데이터베이스에서 검색 가능한 암호화를 구현하는 가장 간단한 방법입니다. 복합 비컨은 기본적 일반 텍스트 문자열과 표준 비컨을 결합하여 보다 복잡한 쿼리를 수행합니다.

비컨은 채워지지 않은 새 데이터베이스에 구현되도록 설계되었습니다. 기존 데이터베이스에 구성된 모든 비컨은 데이터베이스에 기록된 새 레코드만 매핑합니다. 비컨은 필드의 일반 텍스트 값에서 계산됩니다. 필드가 암호화되면 비컨이 기존 데이터를 매핑할 방법이 없습니다. 비컨으로 새 레코드를 작성한 후에는 비컨의 구성을 업데이트할 수 없습니다. 하지만 레코드에 추가하는 새 필드에 대해 새 비컨을 추가할 수 있습니다.

액세스 패턴을 파악한 후에는 데이터베이스 구현의 두 번째 단계로 비컨을 구성해야 합니다. 그런 다음 모든 비컨을 구성한 후 [AWS KMS 계층적 키링](use-hierarchical-keyring.md)을 생성하고, 비컨 버전을 정의하고, [각 비컨에 대한 보조 인덱스를 구성](ddb-searchable-encryption.md#ddb-beacon-indexes)하고, [암호화 작업을](concepts.md#crypt-actions) 정의하고, 데이터베이스 및 AWS Database Encryption SDK 클라이언트를 구성해야 합니다. 자세한 내용은 [비컨 사용](using-beacons.md)을 참조하세요.

비컨 버전을 더 쉽게 정의하려면 표준 및 복합 비컨에 대한 목록을 만드는 것이 좋습니다. 생성한 각 비컨을 구성할 때 해당 표준 또는 복합 비컨 목록에 추가합니다.

**Topics**
+ [표준 비컨 구성](#config-standard-beacons)
+ [복합 비컨 설정](#config-compound-beacons)
+ [구성의 예](beacon-config-examples.md)

## 표준 비컨 구성
<a name="config-standard-beacons"></a>

[표준 비컨](beacons.md#standard-beacon-overview)은 데이터베이스에서 검색 가능한 암호화를 구현하는 가장 간단한 방법입니다. 암호화된 필드 또는 가상 필드 하나에 대해서만 동등 검색을 수행할 수 있습니다.

### 구성 구문의 예제
<a name="standard-config-syntax"></a>

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

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beaconName")
    .length(beaconLengthInBits)
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

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

```
var standardBeaconList = new List<StandardBeacon>();
StandardBeacon exampleStandardBeacon = new StandardBeacon
  {
    Name = "beaconName",
    Length = 10
  };
standardBeaconList.Add(exampleStandardBeacon);
```

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

```
let standard_beacon_list = vec![
    StandardBeacon::builder().name("beacon_name").length(beacon_length_in_bits).build()?,
```

------

표준 비컨을 구성하기 위해서는 다음 값을 제공해야 합니다.

**비컨 이름**  
암호화된 필드를 쿼리할 때 사용하는 이름.  
비컨 이름은 암호화된 필드 또는 가상 필드와 같은 이름일 수 있지만 암호화되지 않은 필드와 같은 이름일 수는 없습니다. 가능하면 표준 비컨을 구성하는 데 사용할 암호화된 필드 또는 [가상 필드](beacons.md#virtual-field)의 이름을 사용하는 것이 좋습니다. 서로 다른 두 비컨은 동일한 비컨 이름을 가질 수 없습니다. 구현에 가장 적합한 비컨 이름을 결정하는 데 도움이 필요하면 [비컨 이름 선](choosing-beacon-name.md)택을 참조하세요.

**비컨 길이**  
잘라낸 후에도 유지되는 비컨 해시 값의 비트 수입니다.  
비컨 길이에 따라 해당 비컨에서 생성되는 평균 오탐 수가 결정됩니다. 구현에 적합한 비컨 길이를 결정하는 데 도움이 되는 자세한 내용 및 도움말은 [비컨 길이 결정](choosing-beacon-length.md)을 참조하세요.

**비컨 소스(선택 사항)**  
표준 비컨을 구성하는 데 사용되는 필드입니다.  
비컨 소스는 필드 이름이거나 중첩된 필드의 값을 참조하는 인덱스이어야 합니다. 비컨 이름이 비컨 소스와 동일한 경우 구성에서 비컨 소스를 생략할 수 있으며 AWS Database Encryption SDK는 비컨 이름을 비컨 소스로 자동으로 사용합니다.

### 가상 필드 생성
<a name="create-virtual-field"></a>

[가상 필드](beacons.md#virtual-field)를 만들려면 가상 필드의 이름과 원본 필드 목록을 제공해야 합니다. 가상 부분 목록에 원본 필드를 추가하는 순서에 따라 가상 필드를 작성할 때 원본 필드를 연결하는 순서가 결정됩니다. 다음 예제에서는 원본 필드 두 개를 완전히 연결하여 가상 필드를 만듭니다.

**참고**  
데이터베이스를 채우기 전에 가상 필드가 예상 결과를 생성하는지 확인하는 것이 좋습니다. 자세한 내용은 비[컨 출력 테스트를](ddb-searchable-encryption.md#ddb-beacon-testing) 참조하세요.

------
#### [ 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) 

```
List<VirtualPart> virtualPartList = new ArrayList<>();
    virtualPartList.add(sourceField1);
    virtualPartList.add(sourceField2);

VirtualField virtualFieldName = VirtualField.builder()
    .name("virtualFieldName")
    .parts(virtualPartList)
    .build();

List<VirtualField> virtualFieldList = new ArrayList<>();
    virtualFieldList.add(virtualFieldName);
```

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

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

```
var virtualPartList = new List<VirtualPart> { sourceField1, sourceField2 };

var virtualFieldName = new VirtualField
{
    Name = "virtualFieldName",
    Parts = virtualPartList
};

var virtualFieldList = new List<VirtualField> { virtualFieldName };
```

------
#### [ 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) 

```
let virtual_part_list = vec![source_field_one, source_field_two];

let state_and_has_test_result_field = VirtualField::builder()
    .name("virtual_field_name")
    .parts(virtual_part_list)
    .build()?;

let virtual_field_list = vec![virtual_field_name];
```

------

원본 필드의 특정 세그먼트를 사용하여 가상 필드를 만들려면 원본 필드를 가상 부분 목록에 추가하기 전에 해당 변환을 정의해야 합니다.

#### 가상 필드에 대한 보안 고려 사항
<a name="virtual-field-considerations"></a>

비컨은 필드의 암호화된 상태를 변경하지 않습니다. 그러나 비컨을 사용할 때 쿼리의 효율성과 데이터 분포에 대해 공개되는 정보의 양 사이에는 본질적인 균형이 있습니다. 비컨을 구성하는 방식에 따라 해당 비컨이 보존하는 보안 수준이 결정됩니다.

소스 필드가 기존 표준 비컨과 겹치는 가상 필드를 만들지 마세요. 표준 비컨을 만드는 데 이미 사용된 소스 필드를 포함하는 가상 필드를 만들면 두 비컨의 보안 수준이 낮아질 수 있습니다. 보안이 약화되는 정도는 추가 소스 필드에서 추가한 엔트로피 수준에 따라 달라집니다. 엔트로피 수준은 추가 소스 필드의 고유 값 분포와 추가 소스 필드가 가상 필드의 전체 크기에 기여하는 비트 수에 따라 결정됩니다.

모집단 및 [비컨 길이](choosing-beacon-length.md)를 사용하여 가상 필드의 원본 필드가 데이터 세트의 보안을 유지하는지 확인할 수 있습니다. 모집단은 필드의 예상 고유 값 수입니다. 모집단은 정확할 필요는 없습니다. 필드의 모집단을 추정하는 데 도움이 필요하면 [모집단 추정](choosing-beacon-length.md#estimate-population)을 참조하세요.

가상 필드의 보안을 검토할 때 다음 예제를 고려하세요.
+ Beacon1은 `FieldA`로 구성됩니다. `FieldA`의 모집단은 **2(Beacon1 길이)**보다 큽니다.
+ Beacon2는 `VirtualField`으로 구성되어 있는데 이는 `FieldA`, `FieldB`, `FieldC`, 및 `FieldD`로 구성되어 있습니다. `FieldB`, `FieldC`, 및 `FieldD`을 합친 모집단은 **2N** 이상입니다.

다음 설명이 참인 경우 Beacon2는 Beacon1과 Beacon2의 보안을 모두 유지합니다.

```
N ≥ (Beacon1 length)/2
```

및

```
N ≥ (Beacon2 length)/2
```

### 비컨 스타일 정의
<a name="define-beacon-styles"></a>

표준 비컨을 사용하여 암호화된 필드 또는 가상 필드를 동등하게 검색할 수 있습니다. 또는 복합 비컨을 구성하여 더 복잡한 데이터베이스 작업을 수행하는 데 사용할 수 있습니다. 표준 비컨을 구성하고 관리하는 데 도움이 되도록 AWS Database Encryption SDK는 표준 *비컨의 용도를 정의하는 다음과 같은 선택적 비컨 스타일을* 제공합니다.

**참고**  
비컨 스타일을 정의하려면 AWS Database Encryption SDK 버전 3.2 이상을 사용해야 합니다. 비컨 구성에 비컨 스타일을 추가하기 전에 모든 리더에 새 버전을 배포합니다.

------
#### [ PartOnly ]

로 정의된 표준 비컨은 복합 비컨의 [암호화된 부분을](#encrypted-parts) 정의하는 데만 사용할 `PartOnly` 수 있습니다. `PartOnly` 표준 비컨은 직접 쿼리할 수 없습니다.

**Java**  

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beaconName")
    .length(beaconLengthInBits)
    .style(
        BeaconStyle.builder()
           .partOnly(PartOnly.builder().build())
        .build()
    )
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

**C\$1/.NET**  

```
new StandardBeacon
{
    Name = "beaconName",
    Length = beaconLengthInBits,
    Style = new BeaconStyle
    {
        PartOnly = new PartOnly()
    }
}
```

**Rust**  

```
StandardBeacon::builder()
    .name("beacon_name")
    .length(beacon_length_in_bits)
    .style(BeaconStyle::PartOnly(PartOnly::builder().build()?))
    .build()?
```

------
#### [ Shared ]

기본적으로 모든 표준 비컨은 비컨 계산을 위해 고유한 HMAC 키를 생성합니다. 따라서 두 개의 개별 표준 비컨에서 암호화된 필드에 대해 동등 검색을 수행할 수 없습니다. 로 정의된 표준 비컨은 계산에 다른 표준 비컨의 HMAC 키를 `Shared` 사용합니다.

예를 들어 `beacon1` 필드를 필드와 비교해야 하는 경우 계산에의 HMAC 키를 사용하는 `Shared` 비컨`beacon2`으로 `beacon1`를 `beacon2` 정의합니다.

**참고**  
비`Shared`컨을 구성하기 전에 보안 및 성능 요구 사항을 고려하세요. `Shared` 비컨은 데이터 세트 배포에 대해 식별할 수 있는 통계 정보의 양을 늘릴 수 있습니다. 예를 들어 동일한 일반 텍스트 값을 포함하는 공유 필드를 공개할 수 있습니다.

**Java**  

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beacon2")
    .length(beaconLengthInBits)
    .style(
        BeaconStyle.builder()
           .shared(Shared.builder().other("beacon1").build())
        .build()
    )
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

**C\$1/.NET**  

```
new StandardBeacon
{
    Name = "beacon2",
    Length = beaconLengthInBits,
    Style = new BeaconStyle
    {
        Shared = new Shared { Other = "beacon1" }
    }
}
```

**Rust**  

```
StandardBeacon::builder()
    .name("beacon2")
    .length(beacon_length_in_bits)
    .style(BeaconStyle::Shared(
       Shared::builder().other("beacon1").build()?,
    ))
    .build()?
```

------
#### [ AsSet ]

기본적으로 필드 값이 집합인 경우 AWS Database Encryption SDK는 집합에 대한 단일 표준 비컨을 계산합니다. 따라서가 암호화된 필드`CONTAINS(a, :value)`인 쿼리`a`는 수행할 수 없습니다. 로 정의된 표준 비컨은 집합의 각 개별 요소에 대한 개별 표준 비컨 값을 `AsSet` 계산하고 항목에 비컨 값을 집합으로 저장합니다. 이렇게 하면 AWS Database Encryption SDK가 쿼리를 수행할 수 있습니다`CONTAINS(a, :value)`.

`AsSet` 표준 비컨을 정의하려면 집합의 요소가 모두 동일한 비[컨 길이를](choosing-beacon-length.md) 사용할 수 있도록 동일한 집단의 요소여야 합니다. 비컨 값을 계산할 때 충돌이 있는 경우 비컨 세트의 요소가 일반 텍스트 세트보다 적을 수 있습니다.

**참고**  
비`AsSet`컨을 구성하기 전에 보안 및 성능 요구 사항을 고려하세요. `AsSet` 비컨은 데이터 세트 배포에 대해 식별할 수 있는 통계 정보의 양을 늘릴 수 있습니다. 예를 들어 일반 텍스트 세트의 크기를 나타낼 수 있습니다.

**Java**  

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beaconName")
    .length(beaconLengthInBits)
    .style(
        BeaconStyle.builder()
           .asSet(AsSet.builder().build())
        .build()
    )
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

**C\$1/.NET**  

```
new StandardBeacon
{
    Name = "beaconName",
    Length = beaconLengthInBits,
    Style = new BeaconStyle
    {
        AsSet = new AsSet()
    }
}
```

**Rust**  

```
StandardBeacon::builder()
    .name("beacon_name")
    .length(beacon_length_in_bits)
    .style(BeaconStyle::AsSet(AsSet::builder().build()?))
    .build()?
```

------
#### [ SharedSet ]

로 정의된 표준 비컨은 `Shared` 및 `AsSet` 함수를 `SharedSet` 결합하여 집합 및 필드의 암호화된 값에 대해 동등 검색을 수행할 수 있습니다. 이렇게 하면 AWS Database Encryption SDK가 `CONTAINS(a, b)``a`가 암호화된 세트이고 `b`가 암호화된 필드인 쿼리를 수행할 수 있습니다.

**참고**  
비`Shared`컨을 구성하기 전에 보안 및 성능 요구 사항을 고려하세요. `SharedSet` 비컨은 데이터 세트 배포에 대해 식별할 수 있는 통계 정보의 양을 늘릴 수 있습니다. 예를 들어 일반 텍스트 세트의 크기 또는 동일한 일반 텍스트 값을 포함하는 공유 필드를 공개할 수 있습니다.

**Java**  

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beacon2")
    .length(beaconLengthInBits)
    .style(
        BeaconStyle.builder()
           .sharedSet(SharedSet.builder().other("beacon1").build())
        .build()
    )
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

**C\$1/.NET**  

```
new StandardBeacon
{
    Name = "beacon2",
    Length = beaconLengthInBits,
    Style = new BeaconStyle
    {
        SharedSet = new SharedSet { Other = "beacon1" }
    }
}
```

**Rust**  

```
StandardBeacon::builder()
    .name("beacon2")
    .length(beacon_length_in_bits)
    .style(BeaconStyle::SharedSet(
        SharedSet::builder().other("beacon1").build()?,
    ))
    .build()?
```

------

## 복합 비컨 설정
<a name="config-compound-beacons"></a>

복합 비컨은 기본 일반 텍스트 문자열과 표준 비컨을 결합하여 단일 인덱스에서 서로 다른 두 가지 레코드 유형을 쿼리하거나 정렬 키로 필드 조합을 쿼리하는 등 복잡한 데이터베이스 작업을 수행합니다. 복합 비컨은 `ENCRYPT_AND_SIGN`, `SIGN_ONLY`및 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 필드로 구성할 수 있습니다. 복합 비컨에 포함된 모든 암호화된 필드에 대해 표준 비컨을 만들어야 합니다.

**참고**  
데이터베이스를 채우기 전에 복합 비컨이 예상 결과를 생성하는지 확인하는 것이 좋습니다. 자세한 내용은 비[컨 출력 테스트를](ddb-searchable-encryption.md#ddb-beacon-testing) 참조하세요.

### 구성 구문의 예제
<a name="compound-config-syntax"></a>

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

**복합 비컨 구성**

다음 예제에서는 복합 비컨 구성 내에서 로컬로 암호화된 부분 목록과 서명된 부분 목록을 정의합니다.

```
List<CompoundBeacon> compoundBeaconList = new ArrayList<>();
CompoundBeacon exampleCompoundBeacon = CompoundBeacon.builder()
    .name("compoundBeaconName")
    .split(".")
    .encrypted(encryptedPartList) 
    .signed(signedPartList)                       
    .constructors(constructorList) 
    .build();
compoundBeaconList.add(exampleCompoundBeacon);
```

**비컨 버전 정의**

다음 예제에서는 비컨 버전에서 암호화되고 서명된 부분 목록을 전역적으로 정의합니다. 비컨 버전 정의에 대한 자세한 내용은 [비컨 사용을 참조하세요](using-beacons.md).

```
 List<BeaconVersion> beaconVersions = new ArrayList<>();
beaconVersions.add(
    BeaconVersion.builder()
        .standardBeacons(standardBeaconList)
        .compoundBeacons(compoundBeaconList)
        .encryptedParts(encryptedPartList)
        .signedParts(signedPartList)
        .version(1) // MUST be 1
        .keyStore(keyStore)
        .keySource(BeaconKeySource.builder()
            .single(SingleKeyStore.builder()
                .keyId(branchKeyId)
                .cacheTTL(6000)
                .build())
            .build())
        .build()
);
```

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

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

**복합 비컨 구성**

다음 예제에서는 복합 비컨 구성 내에서 로컬로 암호화된 부분 목록과 서명된 부분 목록을 정의합니다.

```
var compoundBeaconList = new List<CompoundBeacon>();       
var exampleCompoundBeacon = new CompoundBeacon
 {
    Name = "compoundBeaconName",
    Split = ".",
    Encrypted = encryptedPartList,
    Signed = signedPartList,                        
    Constructors = constructorList 
 };
compoundBeaconList.Add(exampleCompoundBeacon);
```

**비컨 버전 정의**

다음 예제에서는 비컨 버전에서 암호화되고 서명된 부분 목록을 전역적으로 정의합니다. 비컨 버전 정의에 대한 자세한 내용은 [비컨 사용을 참조하세요](using-beacons.md).

```
var beaconVersions = new List<BeaconVersion>
{
    new BeaconVersion
    {
        StandardBeacons = standardBeaconList,
        CompoundBeacons = compoundBeaconList,
        EncryptedParts = encryptedPartsList,
        SignedParts = signedPartsList,
        Version = 1, // MUST be 1
        KeyStore = keyStore,
        KeySource = new BeaconKeySource
        {
            Single = new SingleKeyStore
            {
                KeyId = branchKeyId,
                CacheTTL = 6000
            }
        }
    }
};
```

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

**전체 코드 샘플 참조**: [beacon\$1config.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/complexexample/beacon_config.rs)

**복합 비컨 구성**

다음 예제에서는 복합 비컨 구성 내에서 로컬로 암호화된 부분 목록과 서명된 부분 목록을 정의합니다.

```
let compound_beacon_list = vec![
    CompoundBeacon::builder()
        .name("compound_beacon_name")
        .split(".")
        .encrypted(encrypted_parts_list)
        .signed(signed_parts_list)
        .constructors(constructor_list)
        .build()?
```

**비컨 버전 정의**

다음 예제에서는 비컨 버전에서 암호화되고 서명된 부분 목록을 전역적으로 정의합니다. 비컨 버전 정의에 대한 자세한 내용은 [비컨 사용을 참조하세요](using-beacons.md).

```
let beacon_versions = BeaconVersion::builder()
    .standard_beacons(standard_beacon_list)
    .compound_beacons(compound_beacon_list)
    .encrypted_parts(encrypted_parts_list)
    .signed_parts(signed_parts_list)
    .version(1) // MUST be 1
    .key_store(key_store.clone())
    .key_source(BeaconKeySource::Single(
        SingleKeyStore::builder()
            .key_id(branch_key_id)
            .cache_ttl(6000)
            .build()?,
    ))
    .build()?;
let beacon_versions = vec![beacon_versions];
```

------

로컬 또는 전역적으로 정의된 목록에서 [암호화된 부분](#encrypted-parts)과 [서명된 부분을](#signed-parts) 정의할 수 있습니다. 가능하면 비[컨 버전의](using-beacons.md#beacon-version) 글로벌 목록에 암호화 및 서명된 부분을 정의하는 것이 좋습니다. 암호화되고 서명된 부분을 전역적으로 정의하면 각 부분을 한 번 정의한 다음 여러 복합 비컨 구성에서 해당 부분을 재사용할 수 있습니다. 암호화되거나 서명된 부분을 한 번만 사용하려는 경우 복합 비컨 구성의 로컬 목록에서 정의할 수 있습니다. [생성자 목록에서](#constructor-parts) 로컬 부분과 글로벌 부분을 모두 참조할 수 있습니다.

암호화 및 서명된 부분 목록을 전역적으로 정의하는 경우 복합 비컨이 복합 비컨 구성의 필드를 조합할 수 있는 가능한 모든 방법을 식별하는 생성자 부분 목록을 제공해야 합니다.

**참고**  
암호화 및 서명된 부분 목록을 전역적으로 정의하려면 AWS Database Encryption SDK 버전 3.2 이상을 사용해야 합니다. 새 부분을 전역적으로 정의하기 전에 모든 리더에 새 버전을 배포합니다.  
암호화되고 서명된 부분 목록을 전역적으로 정의하도록 기존 비컨 구성을 업데이트할 수 없습니다.

복합 비컨을 구성하기 위해서는 다음 값을 제공해야 합니다.

**비컨 이름**  
암호화된 필드를 쿼리할 때 사용하는 이름.  
비컨 이름은 암호화된 필드 또는 가상 필드와 같은 이름일 수 있지만 암호화되지 않은 필드와 같은 이름일 수는 없습니다. 두 비컨이 동일한 비컨 이름을 가질 수는 없습니다. 구현에 가장 적합한 비컨 이름을 결정하는 데 도움이 필요하면 [비컨 이름 선](choosing-beacon-name.md)택을 참조하세요.

**분할 캐릭터**  
복합 비컨을 구성하는 부분을 구분하는 데 사용되는 문자입니다.  
복합 비컨을 구성하는 모든 필드의 일반 텍스트 값에는 분할 문자가 나타날 수 없습니다.

**암호화된 부분 목록**  
복합 비컨에 포함된 `ENCRYPT_AND_SIGN` 필드를 식별합니다.  
각 부분에는 이름과 접두사가 포함되어야 합니다. 부분 이름은 암호화된 필드로 구성된 표준 비컨의 이름이어야 합니다. 접두사는 임의의 문자열일 수 있지만 고유해야 합니다. 암호화된 부분은 서명된 부분과 동일한 접두사를 가질 수 없습니다. 부분을 복합 비컨이 제공하는 다른 부분과 구분하는 짧은 값을 사용하는 것이 좋습니다.  
가능하면 암호화된 부분을 전역적으로 정의하는 것이 좋습니다. 하나의 복합 비컨에서만 사용하려는 경우 암호화된 부분을 로컬에서 정의하는 것이 좋습니다. 로컬에서 정의된 암호화된 부분은 전역적으로 정의된 암호화된 부분과 동일한 접두사 또는 이름을 가질 수 없습니다.  

```
List<EncryptedPart> encryptedPartList = new ArrayList<>();
EncryptedPart encryptedPartExample = EncryptedPart.builder()
    .name("standardBeaconName")
    .prefix("E-")
    .build();
encryptedPartList.add(encryptedPartExample);
```

```
var encryptedPartList = new List<EncryptedPart>();
var encryptedPartExample = new EncryptedPart
 {
    Name = "compoundBeaconName",
    Prefix = "E-"
 };
encryptedPartList.Add(encryptedPartExample);
```

```
let encrypted_parts_list = vec![
    EncryptedPart::builder()
        .name("standard_beacon_name")
        .prefix("E-")
        .build()?
];
```

**서명된 부분 목록**  
복합 비컨에 포함된 서명된 필드를 식별합니다.  
서명된 부분은 선택 사항입니다. 서명된 부분을 참조하지 않는 복합 비컨을 구성할 수 있습니다.
각 부분에는 이름, 출처 및 접두사가 포함되어야 합니다. 소스는 파트가 식별하는 `SIGN_ONLY` 또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 필드입니다. 소스는 필드 이름이거나 중첩된 필드의 값을 참조하는 인덱스이어야 합니다. 파트 이름이 소스를 식별하는 경우 소스를 생략하면 AWS Database Encryption SDK가 자동으로 이름을 소스로 사용합니다. 가능하면 소스를 부분 이름으로 지정하는 것이 좋습니다. 접두사는 임의의 문자열일 수 있지만 고유해야 합니다. 서명된 부분은 암호화된 부분과 동일한 접두사를 가질 수 없습니다. 부분을 복합 비컨이 제공하는 다른 부분과 구분하는 짧은 값을 사용하는 것이 좋습니다.  
가능하면 서명된 부분을 전역적으로 정의하는 것이 좋습니다. 하나의 복합 비컨에서만 사용하려는 경우 서명된 부분을 로컬에서 정의하는 것이 좋습니다. 로컬에서 정의된 서명된 부분은 전역적으로 정의된 서명된 부분과 동일한 접두사 또는 이름을 가질 수 없습니다.  

```
List<SignedPart> signedPartList = new ArrayList<>();
SignedPart signedPartExample = SignedPart.builder()
    .name("signedFieldName")
    .prefix("S-")
    .build();
signedPartList.add(signedPartExample);
```

```
var signedPartsList = new List<SignedPart>
{
    new SignedPart { Name = "signedFieldName1", Prefix = "S-" },
    new SignedPart { Name = "signedFieldName2", Prefix = "SF-" }
};
```

```
let signed_parts_list = vec![
    SignedPart::builder()
        .name("signed_field_name_1")
        .prefix("S-")
        .build()?,
   SignedPart::builder()
        .name("signed_field_name_2")
        .prefix("SF-")
        .build()?,     
];
```

**생성자 목록**  
암호화되고 서명된 부분을 복합 비컨으로 조합할 수 있는 다양한 방법을 정의하는 *생성자*를 식별합니다. 생성자 목록에서 로컬 부분과 글로벌 부분을 모두 참조할 수 있습니다.  
전역적으로 정의된 암호화 및 서명된 부분으로 복합 비컨을 구성하는 경우 생성자 목록을 제공해야 합니다.  
전역적으로 정의된 암호화되거나 서명된 부분을 사용하여 복합 비컨을 구성하지 않는 경우 생성자 목록은 선택 사항입니다. 생성자 목록을 지정하지 않으면 AWS Database Encryption SDK는 다음 기본 생성자를 사용하여 복합 비컨을 어셈블합니다.  
+ 서명된 모든 부분은 서명된 부분 목록에 추가된 순서대로
+ 암호화된 모든 부분(암호화된 부분 목록에 추가된 순서대로)
+ 모든 부분이 필요합니다.  
**Constructors**  
각 생성자는 복합 비컨을 조합할 수 있는 한 가지 방법을 정의하는 *생성자 부분*의 정렬된 목록입니다. 생성자 부분은 목록에 추가된 순서대로 함께 결합되며 각 부분은 지정된 분할 문자로 구분됩니다.  
각 생성자 부분은 암호화된 부분이나 서명된 부분의 이름을 지정하고 생성자 내에서 해당 부분이 필수인지 아니면 선택적인지 정의합니다. 예를 들어 `Field1`, `Field1.Field2`, 및 `Field1.Field2.Field3`에 대한 복합 비컨을 조회하고자 한다면, `Field2` 및 `Field3`을 선택 사항으로 표시하고 생성자를 하나 생성합니다.  
생성자마다 필수 부분이 하나 이상 있어야 합니다. 쿼리에 `BEGINS_WITH` 연산자를 사용할 수 있도록 각 생성자의 첫 번째 부분을 필수로 설정하는 것이 좋습니다.  
생성자의 필수 부분이 모두 레코드에 있으면 생성자는 성공합니다. 새 레코드를 작성할 때 복합 비컨은 생성자 목록을 사용하여 제공된 값에서 비컨을 조합할 수 있는지 여부를 결정합니다. 생성자 목록에 생성자가 추가된 순서대로 비컨을 조합하려고 시도하고 성공한 첫 번째 생성자를 사용합니다. 생성자가 성공하지 못하면 비컨이 레코드에 기록되지 않습니다.  
쿼리 결과가 정확한지 확인하려면 모든 리더와 작성자가 동일한 순서의 생성자를 지정해야 합니다.
다음 절차에 따라 생성자 목록을 지정하세요.  

1. 암호화된 각 부분과 서명된 부분에 대한 생성자 부분을 만들어 해당 부분이 필요한지 여부를 정의합니다.

   생성자 부분 이름은 생성자가 나타내는 표준 비컨 또는 서명된 필드의 이름이어야 합니다.

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

   ```
   ConstructorPart field1ConstructorPart = ConstructorPart.builder()
           .name("Field1")
           .required(true)
           .build();
   ```

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

   ```
   var field1ConstructorPart = new ConstructorPart { Name = "Field1", Required = true };
   ```

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

   ```
   let field_1_constructor_part = ConstructorPart::builder()
       .name("field_1")
       .required(true)
       .build()?;
   ```

------

1. **1단계**에서 만든 생성자 부분을 사용하여 복합 비컨을 조합할 수 있도록 가능한 모든 방법에 맞는 생성자를 만듭니다.

   예를 들어 `Field1.Field2.Field3` 및 `Field4.Field2.Field3`에 대해 쿼리하려면 두 개의 생성자를 만들어야 합니다. `Field1` 및 `Field4`은 두 개의 별도 생성자에 정의되어 있으므로 둘 다 필요할 수 있습니다.

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

   ```
   // Create a list for Field1.Field2.Field3 queries
   List<ConstructorPart> field123ConstructorPartList = new ArrayList<>();
   field123ConstructorPartList.add(field1ConstructorPart);
   field123ConstructorPartList.add(field2ConstructorPart);
   field123ConstructorPartList.add(field3ConstructorPart);
   Constructor field123Constructor = Constructor.builder()
           .parts(field123ConstructorPartList)
           .build();
   // Create a list for Field4.Field2.Field1 queries
   List<ConstructorPart> field421ConstructorPartList = new ArrayList<>();
   field421ConstructorPartList.add(field4ConstructorPart);
   field421ConstructorPartList.add(field2ConstructorPart);
   field421ConstructorPartList.add(field1ConstructorPart);
   Constructor field421Constructor = Constructor.builder()
           .parts(field421ConstructorPartList)
           .build();
   ```

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

   ```
   // Create a list for Field1.Field2.Field3 queries
    var field123ConstructorPartList = new Constructor
   {
       Parts = new List<ConstructorPart> { field1ConstructorPart, field2ConstructorPart, field3ConstructorPart }
   };
   // Create a list for Field4.Field2.Field1 queries        
   var field421ConstructorPartList = new Constructor
   {
       Parts = new List<ConstructorPart> { field4ConstructorPart, field2ConstructorPart, field1ConstructorPart }
   };
   ```

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

   ```
   // Create a list for field1.field2.field3 queries
   let field1_field2_field3_constructor = Constructor::builder()
       .parts(vec![
           field1_constructor_part,
           field2_constroctor_part.clone(),
           field3_constructor_part,
       ])
       .build()?;
   
   // Create a list for field4.field2.field1 queries
   let field4_field2_field1_constructor = Constructor::builder()
       .parts(vec![
           field4_constructor_part,
           field2_constroctor_part.clone(),
           field1_constructor_part,
       ])
       .build()?;
   ```

------

1. **2단계**에서 만든 모든 생성자를 포함하는 생성자 목록을 만듭니다.

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

   ```
   List<Constructor> constructorList = new ArrayList<>();
   constructorList.add(field123Constructor);
   constructorList.add(field421Constructor);
   ```

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

   ```
   var constructorList = new List<Constructor>
   {
       field123Constructor,
       field421Constructor
   };
   ```

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

   ```
   let constructor_list = vec![
       field1_field2_field3_constructor,
       field4_field2_field1_constructor,
   ];
   ```

------

1. 복합 비컨을 생성할 `constructorList` 때를 지정합니다.

# 구성의 예
<a name="beacon-config-examples"></a>


****  

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

다음 예제는 표준 및 복합 비컨을 구성하는 방법을 보여 줍니다. 다음 구성은 비컨 길이를 제공하지 않습니다. 구성에 적합한 비컨 길이를 결정하는 데 도움이 필요하면 비컨 길이 [선택](choosing-beacon-length.md)을 참조하세요.

비컨을 구성하고 사용하는 방법을 보여주는 전체 코드 예제를 보려면 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/searchableencryption), [.NET](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/searchableencryption/) 및 [Rust](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/) 검색 가능한 암호화 예제를 참조하세요.

**Topics**
+ [표준 비컨](#standard-config-examples)
+ [복합 비컨](#compound-config-examples)

## 표준 비컨
<a name="standard-config-examples"></a>

정확히 일치하는지 `inspector_id_last4` 필드를 쿼리하려면 다음 구성을 사용하여 표준 비컨을 만듭니다.

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

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("inspector_id_last4")
    .length(beaconLengthInBits)
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

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

```
var standardBeaconList = new List<StandardBeacon>>);
StandardBeacon exampleStandardBeacon = new StandardBeacon
  {
    Name = "inspector_id_last4",
    Length = 10
  };
standardBeaconList.Add(exampleStandardBeacon);
```

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

```
let last4_beacon = StandardBeacon::builder()
    .name("inspector_id_last4")
    .length(10)
    .build()?;
                        
let unit_beacon = StandardBeacon::builder().name("unit").length(30).build()?;

let standard_beacon_list = vec![last4_beacon, unit_beacon];
```

------

## 복합 비컨
<a name="compound-config-examples"></a>

`inspector_id_last4` 및`inspector_id_last4.unit` 에서 `UnitInspection` 데이터베이스를 쿼리하려면 다음 구성으로 복합 비컨을 만듭니다. 이 복합 비컨에는 [암호화된 부분](configure-beacons.md#encrypted-parts)만 필요합니다.

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

```
// 1. Create standard beacons for the inspector_id_last4 and unit fields.
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon inspectorBeacon = StandardBeacon.builder()
    .name("inspector_id_last4")
    .length(beaconLengthInBits)
    .build();
standardBeaconList.add(inspectorBeacon);

StandardBeacon unitBeacon = StandardBeacon.builder()
    .name("unit")
    .length(beaconLengthInBits)
    .build();
standardBeaconList.add(unitBeacon);        

// 2. Define the encrypted parts.
List<EncryptedPart> encryptedPartList = new ArrayList<>();

// Each encrypted part needs a name and prefix
// The name must be the name of the standard beacon
// The prefix must be unique
// For this example we use the prefix "I-" for "inspector_id_last4"
// and "U-" for "unit"
EncryptedPart encryptedPartInspector = EncryptedPart.builder()
    .name("inspector_id_last4")
    .prefix("I-")
    .build();
encryptedPartList.add(encryptedPartInspector);

EncryptedPart encryptedPartUnit = EncryptedPart.builder()
    .name("unit")
    .prefix("U-")
    .build();
encryptedPartList.add(encryptedPartUnit);   

// 3. Create the compound beacon.
// This compound beacon only requires a name, split character, 
// and list of encrypted parts
CompoundBeacon inspectorUnitBeacon = CompoundBeacon.builder()
    .name("inspectorUnitBeacon")
    .split(".")
    .sensitive(encryptedPartList)
    .build();
```

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

```
// 1. Create standard beacons for the inspector_id_last4 and unit fields.
StandardBeacon inspectorBeacon = new StandardBeacon
 {
   Name = "inspector_id_last4",
   Length = 10
 };
standardBeaconList.Add(inspectorBeacon);
StandardBeacon unitBeacon = new StandardBeacon
 {
    Name = "unit",
    Length = 30
 };  
standardBeaconList.Add(unitBeacon);
                
// 2. Define the encrypted parts.
var last4EncryptedPart = new EncryptedPart

// Each encrypted part needs a name and prefix
// The name must be the name of the standard beacon
// The prefix must be unique
// For this example we use the prefix "I-" for "inspector_id_last4"
// and "U-" for "unit"
var last4EncryptedPart = new EncryptedPart
 {
   Name = "inspector_id_last4",
   Prefix = "I-"
 };
encryptedPartList.Add(last4EncryptedPart);

var unitEncryptedPart = new EncryptedPart
 {
   Name = "unit",
   Prefix = "U-"
 };
encryptedPartList.Add(unitEncryptedPart); 

// 3. Create the compound beacon.
// This compound beacon only requires a name, split character, 
// and list of encrypted parts
var compoundBeaconList = new List<CompoundBeacon>>);
var inspectorCompoundBeacon = new CompoundBeacon
  {
      Name = "inspector_id_last4",
      Split = ".",
      Encrypted = encryptedPartList
  };
compoundBeaconList.Add(inspectorCompoundBeacon);
```

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

```
// 1. Create standard beacons for the inspector_id_last4 and unit fields.
let last4_beacon = StandardBeacon::builder()
    .name("inspector_id_last4")
    .length(10)
    .build()?;
                        
let unit_beacon = StandardBeacon::builder().name("unit").length(30).build()?;

let standard_beacon_list = vec![last4_beacon, unit_beacon];
                        
// 2. Define the encrypted parts.
// The name must be the name of the standard beacon
// The prefix must be unique
// For this example we use the prefix "I-" for "inspector_id_last4"
// and "U-" for "unit"
let encrypted_parts_list = vec![
    EncryptedPart::builder()
        .name("inspector_id_last4")
        .prefix("I-")
        .build()?,
    EncryptedPart::builder().name("unit").prefix("U-").build()?,
];

// 3. Create the compound beacon
// This compound beacon only requires a name, split character, 
// and list of encrypted parts
let compound_beacon_list = vec![CompoundBeacon::builder()
    .name("last4UnitCompound")
    .split(".")
    .encrypted(encrypted_parts_list)
    .build()?];
```

------

# 비컨 사용
<a name="using-beacons"></a>


****  

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

비컨을 사용하면 쿼리 중인 전체 데이터베이스를 복호화하지 않고도 암호화된 레코드를 검색할 수 있습니다. 비컨은 채워지지 않은 새 데이터베이스에 구현되도록 설계되었습니다. 기존 데이터베이스에 구성된 모든 비컨은 데이터베이스에 기록된 새 레코드만 매핑합니다. 비컨은 필드의 일반 텍스트 값에서 계산됩니다. 필드가 암호화되면 비컨이 기존 데이터를 매핑할 방법이 없습니다. 비컨으로 새 레코드를 작성한 후에는 비컨의 구성을 업데이트할 수 없습니다. 하지만 레코드에 추가하는 새 필드에 새 비컨을 추가할 수 있습니다.

비컨을 구성한 후에는 데이터베이스를 채우고 비컨에 대한 쿼리를 수행하기 전에 다음 단계를 완료해야 합니다.

1. ** AWS KMS 계층적 키링 생성**

   [검색 가능한 암호화를 사용하려면 [AWS KMS 계층적 키링](use-hierarchical-keyring.md)을 사용하여 레코드 보호에 사용되는 데이터 키](concepts.md#data-key)를 생성, 암호화 및 복호화해야 합니다.

   비컨을 구성한 후 [계층적 키링 사전 요구 사항](use-hierarchical-keyring.md#hierarchical-keyring-prereqs)을 조합하고 [계층적 키링을 생성합니다](use-hierarchical-keyring.md#initialize-hierarchical-keyring).

   계층적 키링이 필요한 이유에 대한 자세한 내용은 [검색 가능한 암호화를 위한 계층적 키링 사용](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings)을 참조하세요.

1. 

   **비컨 버전 정의**

   `keyStore`, `keySource`, 구성한 모든 표준 비컨 목록, 구성한 모든 복합 비컨 목록, 암호화된 부분 목록, 서명된 부분 목록 및 비컨 버전을 지정합니다. 비컨 버전에 대해 `1`을 지정해야 합니다. `keySource` 정의에 대한 지침은 [비컨 키 소스 정의하기](use-hierarchical-keyring.md#beacon-key-source) 섹션을 참조하세요.

   다음 Java 예제는 단일 테넌트 데이터베이스의 비컨 버전을 정의합니다. 멀티테넌트 데이터베이스의 비컨 버전을 정의하는 데 도움이 필요하면 [멀티테넌트 데이터베이스의 검색 가능한 암호화](searchable-encryption-multitenant.md)를 참조하세요.

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

   ```
    List<BeaconVersion> beaconVersions = new ArrayList<>();
   beaconVersions.add(
       BeaconVersion.builder()
           .standardBeacons(standardBeaconList)
           .compoundBeacons(compoundBeaconList)
           .encryptedParts(encryptedPartsList)
           .signedParts(signedPartsList)
           .version(1) // MUST be 1
           .keyStore(keyStore)
           .keySource(BeaconKeySource.builder()
               .single(SingleKeyStore.builder()
                   .keyId(branchKeyId)
                   .cacheTTL(6000)
                   .build())
               .build())
           .build()
   );
   ```

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

   ```
   var beaconVersions = new List<BeaconVersion>
   {
       new BeaconVersion
       {
           StandardBeacons = standardBeaconList,
           CompoundBeacons = compoundBeaconList,
           EncryptedParts = encryptedPartsList,
           SignedParts = signedPartsList,
           Version = 1, // MUST be 1
           KeyStore = branchKeyStoreName,
           KeySource = new BeaconKeySource
           {
               Single = new SingleKeyStore
               {
                   KeyId = branch-key-id,
                   CacheTTL = 6000
               }
           }
       }
   };
   ```

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

   ```
   let beacon_version = BeaconVersion::builder()
       .standard_beacons(standard_beacon_list)
       .compound_beacons(compound_beacon_list)
       .version(1) // MUST be 1
       .key_store(key_store.clone())
       .key_source(BeaconKeySource::Single(
           SingleKeyStore::builder()
               // `keyId` references a beacon key.
               // For every branch key we create in the keystore,
               // we also create a beacon key.
               // This beacon key is not the same as the branch key,
               // but is created with the same ID as the branch key.
               .key_id(branch_key_id)
               .cache_ttl(6000)
               .build()?,
       ))
       .build()?;
   let beacon_versions = vec![beacon_version];
   ```

------

1. **보조 인덱스 구성**

   [비컨을 구성](configure-beacons.md)한 후 암호화된 필드를 검색하려면 먼저 각 비컨을 반영하는 보조 인덱스를 구성해야 합니다. 자세한 내용은 [비컨을 사용한 보조 인덱스 구성](ddb-searchable-encryption.md#ddb-beacon-indexes) 단원을 참조하십시오.

1. **[암호화 작업](concepts.md#crypt-actions) 정의**

   표준 비컨을 구성하는 데 사용되는 모든 필드를 `ENCRYPT_AND_SIGN`으로 표시해야 합니다. 비컨을 구성하는 데 사용되는 다른 모든 필드는 `SIGN_ONLY` 또는 로 표시되어야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`.

1. ** AWS Database Encryption SDK 클라이언트 구성**

   DynamoDB 테이블의 테이블 항목을 보호하는 AWS Database Encryption SDK 클라이언트를 구성하려면 [ DynamoDB용 Java 클라이언트 측 암호화 라이브러리](ddb-java.md)를 참조하세요.

## 비컨 쿼리
<a name="querying-beacons"></a>

구성하는 비컨의 유형에 따라 수행할 수 있는 쿼리 유형이 결정됩니다. 표준 비컨은 필터 표현식을 사용하여 동등 검색을 수행합니다. 복합 비컨은 리터럴 일반 텍스트 문자열과 표준 비컨을 결합하여 복잡한 쿼리를 수행합니다. 암호화된 데이터를 쿼리할 때는 비컨 이름을 검색합니다.

두 표준 비컨에 동일한 기본 일반 텍스트가 포함되어 있더라도 두 표준 비컨의 값을 비교할 수는 없습니다. 두 개의 표준 비컨은 동일한 일반 텍스트 값에 대해 서로 다른 두 개의 HMAC 태그를 생성합니다. 따라서 표준 비컨은 다음 쿼리를 수행할 수 없습니다.
+ `beacon1 = beacon2`
+ `beacon1 IN (beacon2)`
+ `value IN (beacon1, beacon2, ...)`
+ `CONTAINS(beacon1, beacon2)`

복합 비컨은 다음 쿼리를 수행할 수 있습니다.
+ `BEGINS_WITH(a)`, 여기서 `a`는 조립된 복합 비컨이 시작하는 필드의 전체 값을 반영합니다. `BEGINS_WITH` 연산자를 사용하여 특정 하위 문자열로 시작하는 값을 식별할 수 없습니다. 하지만 `BEGINS_WITH(S_)`을 사용할 수 있으며, 여기서 `S_`는 조립된 복합 비컨이 시작하는 부분의 접두사를 반영합니다.
+ `CONTAINS(a)`, 여기서 `a`는 조립된 복합 비컨에 포함된 필드의 전체 값을 반영합니다. `CONTAINS` 연산자를 사용하여 세트 내의 특정 하위 문자열이나 값이 포함된 레코드를 식별할 수 없습니다.

  예를 들어 `a`이 세트의 값을 반영하는 쿼리 `CONTAINS(path, "a"`는 수행할 수 없습니다.
+ 복합 비컨의 [서명된 부분](configure-beacons.md#signed-parts)을 비교할 수 있습니다. 서명된 부분을 비교할 때 선택적으로 하나 이상의 [서명된 부분에 암호화된 부분](configure-beacons.md#encrypted-parts)의 접두사를 추가할 수 있지만 암호화된 필드의 값을 쿼리에 포함할 수는 없습니다.

  예를 들어 서명된 부분을 비교하고 `signedField1 = signedField2` 또는 `value IN (signedField1, signedField2, ...)`에 대해 쿼리할 수 있습니다.

  `signedField1.A_ = signedField2.B_`에 대한 쿼리에 의해 서명된 부분과 암호화된 부분의 접두사를 비교할 수도 있습니다.
+ `field BETWEEN a AND b`, 여기서 `a` 및 `b`는 서명된 부분입니다. 암호화된 부분의 접두사를 하나 이상의 서명된 부분에 선택적으로 추가할 수 있지만 암호화된 필드의 값을 쿼리에 포함할 수는 없습니다.

복합 비컨에 대한 쿼리에 포함시키는 각 부분의 접두사를 포함해야 합니다. 예를 들어, 두 개의 필드, `encryptedField` 및 `signedField`로부터 복합 비컨 `compoundBeacon`을 구성한 경우, 비컨을 쿼리할 때 이 두 부분에 대해 구성된 접두사를 포함해야 합니다.

```
compoundBeacon = E_encryptedFieldValue.S_signedFieldValue
```

# 멀티테넌트 데이터베이스를 위한 검색 가능한 암호화
<a name="searchable-encryption-multitenant"></a>


****  

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

데이터베이스에서 검색 가능한 암호화를 구현하려면 [AWS KMS 계층적 키링](use-hierarchical-keyring.md)을 사용해야 합니다. AWS KMS 계층적 키링은 레코드를 보호하는 데 사용되는 데이터 키를 생성, 암호화 및 해독합니다. 또한 비컨을 생성하는 데 사용되는 비컨 키도 생성합니다. 멀티테넌트 데이터베이스에서 AWS KMS 계층적 키링을 사용하는 경우 각 테넌트에 대해 고유한 브랜치 키와 비컨 키가 있습니다. 멀티테넌트 데이터베이스에서 암호화된 데이터를 쿼리하려면 쿼리하는 비컨을 생성하는 데 사용된 비컨 키 자료를 식별해야 합니다. 자세한 내용은 [검색 가능한 암호화를 위한 계층적 키링 사용](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings) 단원을 참조하십시오.

멀티테넌트 데이터베이스의 [비컨 버전](using-beacons.md#beacon-version)을 정의할 때는 구성한 모든 표준 비컨 목록, 구성한 모든 복합 비컨 목록, 비컨 버전 및 `keySource`을 지정합니다. [비콘 키 소스를 `MultiKeyStore`로 정의하고](use-hierarchical-keyring.md#beacon-key-source) `keyFieldName`을 포함해야 하며, 로컬 비컨 키 캐시에 대한 캐시 수명과 로컬 비컨 키 캐시에 대한 최대 캐시 크기를 포함해야 합니다.

[서명된 비컨](configure.md#signed-beacons)을 구성한 경우 해당 비컨이`compoundBeaconList` 에 포함되어야 합니다. 서명된 비컨은 `SIGN_ONLY` 및 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`필드에 대해 복잡한 쿼리를 인덱싱하고 수행하는 복합 비컨의 한 유형입니다.

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

```
List<BeaconVersion> beaconVersions = new ArrayList<>();
    beaconVersions.add(
        BeaconVersion.builder()
                .standardBeacons(standardBeaconList)
                .compoundBeacons(compoundBeaconList)
                .version(1) // MUST be 1
                .keyStore(branchKeyStoreName)
                .keySource(BeaconKeySource.builder()
                        .multi(MultiKeyStore.builder()
                                .keyFieldName(keyField)
                                .cacheTTL(6000)
                                .maxCacheSize(10)
                        .build())
                .build())
        .build()
    );
```

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

```
var beaconVersions = new List<BeaconVersion>
{
    new BeaconVersion
    {
        StandardBeacons = standardBeaconList,
        CompoundBeacons = compoundBeaconList,
        EncryptedParts = encryptedPartsList,
        SignedParts = signedPartsList,
        Version = 1, // MUST be 1
        KeyStore = branchKeyStoreName,
        KeySource = new BeaconKeySource
        {
            Multi = new MultiKeyStore
            {
                KeyId = branch-key-id,
                CacheTTL = 6000,
                MaxCacheSize = 10
            }
        }
    }
};
```

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

```
let beacon_version = BeaconVersion::builder()
    .standard_beacons(standard_beacon_list)
    .compound_beacons(compound_beacon_list)
    .version(1) // MUST be 1
    .key_store(key_store.clone())
    .key_source(BeaconKeySource::Multi(
        MultiKeyStore::builder()
            // `keyId` references a beacon key.
            // For every branch key we create in the keystore,
            // we also create a beacon key.
            // This beacon key is not the same as the branch key,
            // but is created with the same ID as the branch key.
            .key_id(branch_key_id)
            .cache_ttl(6000)
            .max_cache_size(10)
            .build()?,
    ))
    .build()?;
let beacon_versions = vec![beacon_version];
```

------

**keyFieldName**  
[`keyFieldName`](use-hierarchical-keyring.md#keyFieldName)는 지정된 테넌트에 대한 비컨을 생성하는 데 사용된 비컨 키와 관련된 `branch-key-id`를 저장하는 필드의 이름을 정의합니다.  
데이터베이스에 새 레코드를 쓰는 경우 해당 레코드에 대한 비컨을 생성하는 데 사용되는 비컨 키를 식별하는 `branch-key-id`가 이 필드에 저장됩니다.  
기본적으로 `keyField`는 데이터베이스에 명시적으로 저장되지 않는 개념적 필드입니다. AWS Database Encryption SDK는 [자료 설명](concepts.md#material-description)의 암호화된 [데이터 키](concepts.md#data-key)`branch-key-id`에서를 식별하고 복합 비컨 및 [서명된 비컨](configure.md#signed-beacons)에서 참조할 수 `keyField` 있도록 개념에 값을 저장합니다. 자료 설명은 서명된 것이므로 개념적 `keyField`은 서명된 부분으로 간주됩니다.  
암호화 작업에 `keyField`를 `SIGN_ONLY` 또는 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 필드로 포함하여 데이터베이스에 필드를 명시적으로 저장할 수도 있습니다. 이렇게 하면 데이터베이스에 레코드를 쓸 때마다 `keyField`dp 수동으로 `branch-key-id`를 포함시켜야 합니다.

## 멀티테넌트 데이터베이스의 비컨 쿼리
<a name="query-multitenant-beacons"></a>

비컨을 쿼리하려면 비컨을 재계산하는 데 필요한 적절한 비컨 키 자료를 식별할 수 있도록 쿼리에 `keyField`을 포함해야 합니다. 레코드의 비컨을 생성하는 데 사용되는 비컨 키와 관련된 `branch-key-id`을 지정해야 합니다. 브랜치 키 ID 공급자의 테넌트 `branch-key-id`를 식별하는 [친숙한 이름](use-hierarchical-keyring.md#branch-key-id-supplier)은 지정할 수 없습니다. 다음과 같은 방법으로 쿼리에 `keyField`을 포함시킬 수 있습니다.

**복합 비컨**  
레코드에 `keyField`을 명시적으로 저장하든 저장하지 않든, 복합 비컨에 서명된 부분으로`keyField`을 직접 포함시킬 수 있습니다. `keyField` 서명된 부분이 필요합니다.  
예를 들어, 필드 2개와 `encryptedField` 및 `signedField`를 사용하여 복합 비컨 `compoundBeacon`을 생성하려면 `keyField`를 서명된 부분으로 포함해야 합니다. 이렇게 하면 `compoundBeacon`에서 다음 쿼리를 수행할 수 있습니다.  

```
compoundBeacon = E_encryptedFieldValue.S_signedFieldValue.K_branch-key-id
```

**서명된 비컨**  
 AWS Database Encryption SDK는 표준 및 복합 비컨을 사용하여 검색 가능한 암호화 솔루션을 제공합니다. 이러한 비컨에는 하나 이상의 암호화된 필드가 포함되어야 합니다. 그러나 AWS Database Encryption SDK는 일반 텍스트 `SIGN_ONLY` 및 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 필드에서 완전히 구성할 수 있는 [서명된 비컨](configure.md#signed-beacons)도 지원합니다.  
서명된 비컨은 단일 부분으로 구성할 수 있습니다. `keyField`를 레코드에 명시적으로 저장하든 저장하지 않든, `keyField`에서 서명된 비컨을 생성하고 이를 사용하여 `keyField` 서명된 비컨에 대한 쿼리를 다른 비컨 중 하나에 대한 쿼리와 결합하는 복합 쿼리를 만들 수 있습니다. 예를 들어 다음 쿼리를 수행할 수 있습니다.  

```
keyField = K_branch-key-id AND compoundBeacon = E_encryptedFieldValue.S_signedFieldValue
```
서명된 비컨을 구성하는 데 도움이 필요하면 [서명된 비컨 만들기](configure.md#signed-beacons) 섹션을 참조하세요

**`keyField`에서 직접 쿼리하기**  
암호화 `keyField` 작업에서 `keyField`를 지정하고 레코드에 필드를 명시적으로 저장한 경우, 비컨의 쿼리와 비컨의 쿼리를 결합하는 복합 쿼리를 만들 수 있습니다. 표준 비컨을 쿼리하려는 경우 `keyField`에서 직접 쿼리하도록 선택할 수 있습니다. 예를 들어 다음 쿼리를 수행할 수 있습니다.  

```
keyField = branch-key-id AND standardBeacon = S_standardBeaconValue
```