

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

# 클라이언트 측 필드 레벨 암호화
<a name="field-level-encryption"></a>

Amazon DocumentDB 클라이언트 측 필드 레벨 암호화(FLE)를 사용하면 Amazon DocumentDB 클러스터로 전송하기 전에 클라이언트 애플리케이션의 민감한 데이터를 암호화할 수 있습니다. 민감한 데이터는 클러스터에서 저장 및 처리될 때 암호화된 상태로 유지되며 검색 시 클라이언트 애플리케이션에서 복호화됩니다.

**Topics**
+ [시작하기](#fle-getting-started)
+ [클라이언트 측 FLE의 쿼리](#fle-querying)

## 시작하기
<a name="fle-getting-started"></a>

Amazon DocumentDB에서 클라이언트측 FLE의 초기 구성은 암호화 키 생성, 애플리케이션에 역할 연결, 애플리케이션 구성, 암호화 옵션을 통한 CRUD 작업 정의 등을 포함하는 4단계 프로세스입니다.

**Topics**
+ [1단계: 암호화 키 생성하기](#fle-step-create-key)
+ [2단계: 역할을 애플리케이션에 연결하기](#fle-step-associate-role)
+ [3단계: 애플리케이션 구성](#fle-step-config-app)
+ [4단계: CRUD 작업 정의하기](#fle-step-crud-ops)
+ [예: 클라이언트 측 필드 수준 암호화 구성 파일](#fle-config-example)

### 1단계: 암호화 키 생성하기
<a name="fle-step-create-key"></a>

를 사용하여 민감한 데이터 필드를 암호화 및 해독하는 데 사용되는 대칭 키를 AWS Key Management Service생성하고 필요한 IAM 사용 권한을 제공합니다.는 데이터 키(DKs)를 암호화하는 데 사용되는 고객 키(CK)를 AWS KMS 저장합니다. 고객 키를 KMS에 저장하여 보안 태세를 강화합니다. 데이터 키는 Amazon DocumentDB 컬렉션에 저장되는 보조 키로, 문서를 Amazon DocumentDB에 저장하기 전에 민감한 필드를 암호화하는 데 필요합니다. 고객 키는 데이터 키를 암호화하고, 데이터 키는 다시 데이터를 암호화하고 복호화합니다. 글로벌 클러스터를 사용하는 경우 여러 리전의 다양한 서비스 역할에서 사용할 수 있는 다중 리전 키를 생성할 수 있습니다.

키 생성 방법을 AWS Key Management Service포함하여에 대한 자세한 내용은 *AWS Key Management Service 개발자 안내서*의 [AWS Key Management Service 개념](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html)을 참조하세요.

### 2단계: 역할을 애플리케이션에 연결하기
<a name="fle-step-associate-role"></a>

적절한 AWS KMS 권한을 가진 IAM 정책을 생성합니다. 이 정책은 연결되는 IAM 자격 증명이 리소스 필드에 지정된 KMS 키를 암호화하고 해독하도록 허용합니다. 애플리케이션은 인증할이 IAM 역할을 수임합니다 AWS KMS.

정책은 다음과 비슷할 것입니다.

```
{ "Effect": "Allow",
"Action": ["kms:Decrypt", "kms:Encrypt"],
"Resource": "Customer Key ARN"
}
```

### 3단계: 애플리케이션 구성
<a name="fle-step-config-app"></a>

이제에서 고객 키를 정의하고 IAM 역할을 AWS KMS 생성했으며 고객 키에 액세스할 수 있는 적절한 IAM 권한을 제공했습니다. 필수 패키지를 가져옵니다.

```
import boto3
import json
import base64
from pymongo import MongoClient
from pymongo.encryption import (Algorithm,
                                ClientEncryption)
```

```
# create a session object: 
my_session = boto3.session.Session()

# get access_key and secret_key programmatically using get_frozen_credentials() method:
current_credentials = my_session.get_credentials().get_frozen_credentials()
```

1. KMS 공급자 유형으로 'aws'를 지정하고 이전 단계에서 검색한 계정 자격 증명을 입력합니다.

   ```
   provider = "aws"
   kms_providers = {
       provider: {
           "accessKeyId": current_credentials.access_key,
           "secretAccessKey": current_credentials.secret_key
       }
   }
   ```

1. 데이터 키를 암호화하는 데 사용되는 고객 키를 지정합니다.

   ```
   customer_key = {
   “region”: “AWS region of the customer_key”,
       “key”: “customer_key ARN”
   }
   
   key_vault_namespace = "encryption.dataKeys"
   
   key_alt_name = 'TEST_DATA_KEY'
   ```

1. MongoClient 개체를 구성합니다.

   ```
   client = MongoClient(connection_string)
   
   coll = client.test.coll
   coll.drop()
   
   client_encryption = ClientEncryption(
       kms_providers, # pass in the kms_providers variable from the previous step
       key_vault_namespace = key_vault_namespace,
       client,
       coll.codec_options
   )
   ```

1. 데이터 키를 생성합니다.

   ```
   data_key_id = client_encryption.create_data_key(provider,
       customer_key,
       key_alt_name = [key_alt_name])
   ```

1. 기존 데이터 키를 검색합니다.

   ```
   data_key = DataKey("aws",
       master_key = customer_key)
   key_id = data_key["_id"]
   data_key_id = client[key_vault_namespace].find_one({"_id": key_id})
   ```

### 4단계: CRUD 작업 정의하기
<a name="fle-step-crud-ops"></a>

암호화 옵션을 사용하여 CRUD 작업을 정의합니다.

1. 단일 문서를 작성/읽기/삭제할 컬렉션을 정의합니다.

   ```
   coll = client.gameinfo.users
   ```

1. 명시적 암호화 - 필드를 암호화하고 다음을 삽입합니다.
**참고**  
“key\_id” 또는 “key\_alt\_name” 중 정확히 하나를 입력해야 합니다.

   ```
   encrypted_first_name = client_encryption.encrypt(
       "Jane",
       Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
       key_id=data_key_id
   )
   encrypted_last_name = client_encryption.encrypt(
       "Doe",
       Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
       key_id=data_key_id
   )
   encrypted_dob = client_encryption.encrypt(
       "1990-01-01",
       Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Random,
       key_id=data_key_id
   )
   
   coll.insert_one(
       {"gamerTag": "jane_doe90",
       "firstName": encrypted_first_name,
       "lastName": encrypted_last_name,
       "dateOfBirth":encrypted_dob,
       "Favorite_games":["Halo","Age of Empires 2","Medal of Honor"]
   })
   ```

### 예: 클라이언트 측 필드 수준 암호화 구성 파일
<a name="fle-config-example"></a>

다음 예제에서는 각 {{자리 표시자를}} 자신의 정보로 바꿉니다.

```
# import python packages:
import boto3
import json
import base64
from pymongo import MongoClient
from pymongo.encryption import (Algorithm,
                                ClientEncryption)

def main():
    
    # create a session object:
    my_session = boto3.session.Session()
    
    # get aws_region from session object:
    aws_region = my_session.region_name
    
    # get access_key and secret_key programmatically using get_frozen_credentials() method:
    current_credentials = my_session.get_credentials().get_frozen_credentials()
    provider = "aws"
    
    # define the kms_providers which is later used to create the Data Key:
    kms_providers = {
        provider: {
            "accessKeyId": current_credentials.access_key,
            "secretAccessKey": current_credentials.secret_key
        }
    }
    
    # enter the kms key ARN. Replace the example ARN value.
    kms_arn = "{{arn:aws:kms:us-east-1:123456789:key/abcd-efgh-ijkl-mnop}}"
    customer_key = {
        "region": aws_region,
        "key":kms_arn
    }

    # secrets manager is used to store and retrieve user credentials for connecting to an Amazon DocumentDB cluster. 
    # retrieve the secret using the secret name. Replace the example secret key.
    secret_name = "{{/dev/secretKey}}"
    docdb_credentials = json.loads(my_session.client(service_name = 'secretsmanager', region_name = "us-east-1").get_secret_value(SecretId = secret_name)['SecretString'])

    connection_params = '/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'
    conn_str = 'mongodb://' + docdb_credentials["username"] + ':' + docdb_credentials["password"] + '@' + docdb_credentials["host"] + ':' + str(docdb_credentials["port"]) + connection_params
    client = MongoClient(conn_str) 

    coll = client.test.coll
    coll.drop()
    
    # store the encryption data keys in a key vault collection (having naming convention as db.collection):
    key_vault_namespace = "encryption.dataKeys"
    key_vault_db_name, key_vault_coll_name = key_vault_namespace.split(".", 1)

    # set up the key vault (key_vault_namespace) for this example:
    key_vault = client[key_vault_db_name][key_vault_coll_name]
    key_vault.drop()
    key_vault.create_index("keyAltNames", unique=True)

    client_encryption = ClientEncryption(
        kms_providers,
        key_vault_namespace,
        client,
        coll.codec_options)
    
    # create a new data key for the encrypted field:
    data_key_id = client_encryption.create_data_key(provider, master_key=customer_key, key_alt_names=["some_key_alt_name"], key_material = None)
    
    # explicitly encrypt a field:
    encrypted_first_name = client_encryption.encrypt(
    "Jane",
    Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
    key_id=data_key_id
    )
    coll.insert_one(
    {"gamerTag": "jane_doe90",
    "firstName": encrypted_first_name
    })
    doc = coll.find_one()
    print('Encrypted document: %s' % (doc,))
    
    # explicitly decrypt the field:
    doc["firstName"] = client_encryption.decrypt(doc["firstName"])
    print('Decrypted document: %s' % (doc,))
    
    # cleanup resources:
    client_encryption.close()
    client.close()
    
if __name__ == "__main__":
    main()
```

## 클라이언트 측 FLE의 쿼리
<a name="fle-querying"></a>

Amazon DocumentDB는 클라이언트 측 FLE 암호화 값이 있는 등식 쿼리만 지원합니다.

예를 들어 암호화된 gamerscore가 500인 문서를 쿼리하려면 클라이언트는 명시적 암호화 방법을 사용하여 쿼리 값을 암호화합니다.

```
encrypted_gamerscore_filter = client_encryption.encrypt(
    500,
    Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
    key_id=data_key_id
)

coll.find( {
    "gamerscore" : { "$eq" : encrypted_gamerscore_filter }
} )
```