

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

# AWS Encryption SDK for Python
<a name="python"></a>

이 주제에서는 AWS Encryption SDK for Python를 설치 및 사용하는 방법을 설명합니다. 를 사용한 프로그래밍에 대한 자세한 내용은 GitHub의 [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/) 리포지토리를 AWS Encryption SDK for Python참조하세요. API 설명서는 [문서 읽기](https://aws-encryption-sdk-python.readthedocs.io/en/latest/)를 참조하세요.

**Topics**
+ [

## 사전 조건
](#python-prerequisites)
+ [

## 설치
](#python-installation)
+ [예제](python-example-code.md)

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

를 설치하기 전에 다음 사전 조건이 있는지 AWS Encryption SDK for Python확인합니다.

**지원되는 Python 버전**  
 AWS Encryption SDK for Python 버전 3.2.0 이상에서는 Python 3.8 이상이 필요합니다.  
[AWS 암호화 자료 공급자 라이브러리](https://github.com/aws/aws-cryptographic-material-providers-library)(MPL)는 버전 4.*x*에 AWS Encryption SDK for Python 도입된에 대한 선택적 종속성입니다. MPL을 설치하려는 경우 Python 3.11 이상을 사용해야 합니다.
이전 버전의는 Python 2.7 및 Python 3.4 이상을 AWS Encryption SDK 지원하지만 최신 버전의를 사용하는 것이 좋습니다 AWS Encryption SDK.  
Python을 다운로드하려면 [Python 다운로드](https://www.python.org/downloads/)를 참조하세요.

**Python용 pip 설치 도구**  
`pip`는 Python 3.6 이상 버전에 포함되어 있지만 업그레이드가 필요할 수도 있습니다. `pip` 업그레이드 또는 설치에 관한 자세한 정보는 `pip` 설명서의 [설치](https://pip.pypa.io/en/latest/installation/)를 참조하세요.

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

 AWS Encryption SDK for Python의 최신 버전을 설치합니다.

**참고**  
3.0.0 AWS Encryption SDK for Python 이전의 모든 버전은 [end-of-support 단계에](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle) 있습니다.  
코드나 데이터를 변경하지 않고 버전 2.0.*x* 이상에서 AWS Encryption SDK 의 최신 버전으로 안전하게 업데이트할 수 있습니다. 그러나 버전 2.0.*x*에 도입된 [새로운 보안 기능](about-versions.md#version-2)은 이하 버전과 호환되지 않습니다. 1.7.*x* 이하 버전에서 2.0.*x* 이상 버전으로 업데이트하려면 먼저 AWS Encryption SDK의 최신 1.*x* 버전으로 업데이트해야 합니다. 자세한 내용은 [마이그레이션 AWS Encryption SDK](migration.md)을 참조하세요.

다음 예제와 AWS Encryption SDK for Python같이 `pip`를 사용하여를 설치합니다.

**최신 버전 설치**  

```
pip install "aws-encryption-sdk[MPL]"
```
접`[MPL]`미사는 [AWS 암호화 자료 공급자 라이브러리](https://github.com/aws/aws-cryptographic-material-providers-library)(MPL)를 설치합니다. MPL에는 데이터를 암호화하고 해독하기 위한 구문이 포함되어 있습니다. MPL은 버전 4.*x*에 AWS Encryption SDK for Python 도입된에 대한 선택적 종속성입니다. MPL을 설치하는 것이 좋습니다. 그러나 MPL을 사용하지 않으려는 경우 접`[MPL]`미사를 생략할 수 있습니다.

pip를 사용하여 패키지를 설치 및 업그레이드하는 방법에 대한 자세한 내용은 [패키지 설치](https://packaging.python.org/tutorials/installing-packages/)를 참조하세요.

에는 모든 플랫폼에서 [암호화 라이브러리](https://cryptography.io/en/latest/)(pyca/cryptography)가 AWS Encryption SDK for Python 필요합니다. `pip`의 모든 버전은 `cryptography` 라이브러리를 Windows에 자동으로 설치하고 빌드합니다. `pip` 8.1 이상 버전은 Linux에 `cryptography`를 자동으로 설치하고 빌드합니다. 이하 버전의 `pip`를 사용 중이며 `cryptography` 라이브러리 빌드에 필요한 도구가 Linux 환경에 없는 경우에는 이러한 도구를 설치해야 합니다. 자세한 내용은 [Linux에서 암호화 빌드](https://cryptography.io/en/latest/installation.html#building-cryptography-on-linux)를 참조하세요.

버전 1.10.0 및 2.5.0은 2.5.0과 3.3.2 사이의 [암호화](https://cryptography.io/en/latest/) 종속성을 AWS Encryption SDK for Python 고정합니다. 다른 버전의는 최신 버전의 암호화를 AWS Encryption SDK for Python 설치합니다. 3.3.2 이상 버전의 암호화가 필요한 경우 AWS Encryption SDK for Python의 최신 메이저 버전을 사용하는 것이 좋습니다.

의 최신 개발 버전은 GitHub의 [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/) 리포지토리를 AWS Encryption SDK for Python참조하십시오.

를 설치한 후이 가이드의 [Python 예제 코드를](python-example-code.md) 살펴보 AWS Encryption SDK for Python면서 시작합니다.

# AWS Encryption SDK for Python 예제 코드
<a name="python-example-code"></a>

다음 예제에서는를 사용하여 데이터를 암호화하고 복호화 AWS Encryption SDK for Python 하는 방법을 보여줍니다.

이 섹션의 예제에서는 선택적 [암호화 자료 공급자 라이브러리](https://github.com/aws/aws-cryptographic-material-providers-library) 종속성()과 AWS Encryption SDK for Python 함께 버전 4.*x*를 사용하는 방법을 보여줍니다`aws-cryptographic-material-providers`. 이전 버전을 사용하거나 재료 공급자 라이브러리(MPL)가 없는 설치를 사용하는 예제를 보려면 GitHub의 [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/) 리포지토리 릴리스 목록에서 [릴리스](https://github.com/aws/aws-encryption-sdk-python/releases)를 찾습니다.

MPL과 AWS Encryption SDK for Python 함께 버전 4.*x*를 사용하는 경우 [키링을](choose-keyring.md) 사용하여 [봉투 암호화](concepts.md#envelope-encryption)를 수행합니다. 는 이전 버전에서 사용한 마스터 키 공급자와 호환되는 키링을 AWS Encryption SDK 제공합니다. 자세한 내용은 [키링 호환성](choose-keyring.md#keyring-compatibility) 단원을 참조하십시오. 마스터 키 공급자에서 키링으로 마이그레이션하는 방법에 대한 예제는 GitHub의 `aws-encryption-sdk-python`리포지토리에서 [마이그레이션 예제](https://github.com/aws/aws-encryption-sdk-python/tree/master/examples/src/migration)를 참조하세요.

**Topics**
+ [문자열](#python-example-strings)
+ [바이트 스트림](#python-example-streams)

## 문자열 암호화 및 복호화
<a name="python-example-strings"></a>

다음 예제에서는를 사용하여 문자열을 암호화하고 복호화 AWS Encryption SDK 하는 방법을 보여줍니다. 이 예제에서는 대칭 암호화 KMS 키와 함께 키[AWS KMS 링](use-kms-keyring.md)을 사용합니다.

이 예제에서는 [기본 커밋 정책](migrate-commitment-policy.md)인를 사용하여 AWS Encryption SDK 클라이언트를 인스턴스화합니다`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`. 자세한 내용은 [커밋 정책 설정](migrate-commitment-policy.md) 단원을 참조하십시오.

```
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
This example sets up the KMS Keyring

The AWS KMS keyring uses symmetric encryption KMS keys to generate, encrypt and
decrypt data keys. This example creates a KMS Keyring and then encrypts a custom input EXAMPLE_DATA
with an encryption context. This example also includes some sanity checks for demonstration:
1. Ciphertext and plaintext data are not the same
2. Encryption context is correct in the decrypted message header
3. Decrypted plaintext value matches EXAMPLE_DATA
These sanity checks are for demonstration in the example only. You do not need these in your code.

AWS KMS keyrings can be used independently or in a multi-keyring with other keyrings
of the same or a different type.

"""

import boto3
from aws_cryptographic_material_providers.mpl import AwsCryptographicMaterialProviders
from aws_cryptographic_material_providers.mpl.config import MaterialProvidersConfig
from aws_cryptographic_material_providers.mpl.models import CreateAwsKmsKeyringInput
from aws_cryptographic_material_providers.mpl.references import IKeyring
from typing import Dict  # noqa pylint: disable=wrong-import-order

import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy

EXAMPLE_DATA: bytes = b"Hello World"


def encrypt_and_decrypt_with_keyring(
    kms_key_id: str
):
    """Demonstrate an encrypt/decrypt cycle using an AWS KMS keyring.

    Usage: encrypt_and_decrypt_with_keyring(kms_key_id)
    :param kms_key_id: KMS Key identifier for the KMS key you want to use for encryption and
    decryption of your data keys.
    :type kms_key_id: string
    
    """
    # 1. Instantiate the encryption SDK client.
    # This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy,
    # which enforces that this client only encrypts using committing algorithm suites and enforces
    # that this client will only decrypt encrypted messages that were created with a committing
    # algorithm suite.
    # This is the default commitment policy if you were to build the client as
    # `client = aws_encryption_sdk.EncryptionSDKClient()`.
    client = aws_encryption_sdk.EncryptionSDKClient(
        commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
    )

    # 2. Create a boto3 client for KMS.
    kms_client = boto3.client('kms', region_name="us-west-2")

    # 3. Optional: create encryption context.
    # Remember that your encryption context is NOT SECRET.
    encryption_context: Dict[str, str] = {
        "encryption": "context",
        "is not": "secret",
        "but adds": "useful metadata",
        "that can help you": "be confident that",
        "the data you are handling": "is what you think it is",
    }

    # 4. Create your keyring
    mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
        config=MaterialProvidersConfig()
    )

    keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput(
        kms_key_id=kms_key_id,
        kms_client=kms_client
    )

    kms_keyring: IKeyring = mat_prov.create_aws_kms_keyring(
        input=keyring_input
    )

    # 5. Encrypt the data with the encryptionContext.
    ciphertext, _ = client.encrypt(
        source=EXAMPLE_DATA,
        keyring=kms_keyring,
        encryption_context=encryption_context
    )

    # 6. Demonstrate that the ciphertext and plaintext are different.
    # (This is an example for demonstration; you do not need to do this in your own code.)
    assert ciphertext != EXAMPLE_DATA, \
        "Ciphertext and plaintext data are the same. Invalid encryption"

    # 7. Decrypt your encrypted data using the same keyring you used on encrypt.
    plaintext_bytes, _ = client.decrypt(
        source=ciphertext,
        keyring=kms_keyring,
        # Provide the encryption context that was supplied to the encrypt method
        encryption_context=encryption_context,
    )

    # 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
    # (This is an example for demonstration; you do not need to do this in your own code.)
    assert plaintext_bytes == EXAMPLE_DATA, \
        "Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
```

## 바이트 스트림 암호화 및 복호화
<a name="python-example-streams"></a>

다음 예제에서는를 사용하여 바이트 스트림을 암호화하고 복호화 AWS Encryption SDK 하는 방법을 보여줍니다. 이 예제에서는 [원시 AES 키링](use-raw-aes-keyring.md)을 사용합니다.

이 예제에서는 [기본 커밋 정책](migrate-commitment-policy.md)인를 사용하여 AWS Encryption SDK 클라이언트를 인스턴스화합니다`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`. 자세한 내용은 [커밋 정책 설정](migrate-commitment-policy.md) 단원을 참조하십시오.

```
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
This example demonstrates file streaming for encryption and decryption.

File streaming is useful when the plaintext or ciphertext file/data is too large to load into
memory. Therefore, the AWS Encryption SDK allows users to stream the data, instead of loading it
all at once in memory. In this example, we demonstrate file streaming for encryption and decryption
using a Raw AES keyring. However, you can use any keyring with streaming.

This example creates a Raw AES Keyring and then encrypts an input stream from the file
`plaintext_filename` with an encryption context to an output (encrypted) file `ciphertext_filename`.
It then decrypts the ciphertext from `ciphertext_filename` to a new file `decrypted_filename`.
This example also includes some sanity checks for demonstration:
1. Ciphertext and plaintext data are not the same
2. Encryption context is correct in the decrypted message header
3. Decrypted plaintext value matches EXAMPLE_DATA
These sanity checks are for demonstration in the example only. You do not need these in your code.

See raw_aes_keyring_example.py in the same directory for another raw AES keyring example
in the AWS Encryption SDK for Python.
"""
import filecmp
import secrets

from aws_cryptographic_material_providers.mpl import AwsCryptographicMaterialProviders
from aws_cryptographic_material_providers.mpl.config import MaterialProvidersConfig
from aws_cryptographic_material_providers.mpl.models import AesWrappingAlg, CreateRawAesKeyringInput
from aws_cryptographic_material_providers.mpl.references import IKeyring
from typing import Dict  # noqa pylint: disable=wrong-import-order

import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy


def encrypt_and_decrypt_with_keyring(
    plaintext_filename: str,
    ciphertext_filename: str,
    decrypted_filename: str
):
    """Demonstrate a streaming encrypt/decrypt cycle.

    Usage: encrypt_and_decrypt_with_keyring(plaintext_filename
                                            ciphertext_filename
                                            decrypted_filename)
    :param plaintext_filename: filename of the plaintext data
    :type plaintext_filename: string
    :param ciphertext_filename: filename of the ciphertext data
    :type ciphertext_filename: string
    :param decrypted_filename: filename of the decrypted data
    :type decrypted_filename: string
    """
    # 1. Instantiate the encryption SDK client.
    # This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy,
    # which enforces that this client only encrypts using committing algorithm suites and enforces
    # that this client will only decrypt encrypted messages that were created with a committing
    # algorithm suite.
    # This is the default commitment policy if you were to build the client as
    # `client = aws_encryption_sdk.EncryptionSDKClient()`.
    client = aws_encryption_sdk.EncryptionSDKClient(
        commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
    )

    # 2. The key namespace and key name are defined by you.
    # and are used by the Raw AES keyring to determine
    # whether it should attempt to decrypt an encrypted data key.
    key_name_space = "Some managed raw keys"
    key_name = "My 256-bit AES wrapping key"

    # 3. Optional: create encryption context.
    # Remember that your encryption context is NOT SECRET.
    encryption_context: Dict[str, str] = {
        "encryption": "context",
        "is not": "secret",
        "but adds": "useful metadata",
        "that can help you": "be confident that",
        "the data you are handling": "is what you think it is",
    }

    # 4. Generate a 256-bit AES key to use with your keyring.
    # In practice, you should get this key from a secure key management system such as an HSM.

    # Here, the input to secrets.token_bytes() = 32 bytes = 256 bits
    static_key = secrets.token_bytes(32)

    # 5. Create a Raw AES keyring
    # We choose to use a raw AES keyring, but any keyring can be used with streaming.
    mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
        config=MaterialProvidersConfig()
    )

    keyring_input: CreateRawAesKeyringInput = CreateRawAesKeyringInput(
        key_namespace=key_name_space,
        key_name=key_name,
        wrapping_key=static_key,
        wrapping_alg=AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16
    )

    raw_aes_keyring: IKeyring = mat_prov.create_raw_aes_keyring(
        input=keyring_input
    )

    # 6. Encrypt the data stream with the encryptionContext
    with open(plaintext_filename, 'rb') as pt_file, open(ciphertext_filename, 'wb') as ct_file:
        with client.stream(
            mode='e',
            source=pt_file,
            keyring=raw_aes_keyring,
            encryption_context=encryption_context
        ) as encryptor:
            for chunk in encryptor:
                ct_file.write(chunk)

    # 7. Demonstrate that the ciphertext and plaintext are different.
    # (This is an example for demonstration; you do not need to do this in your own code.)
    assert not filecmp.cmp(plaintext_filename, ciphertext_filename), \
        "Ciphertext and plaintext data are the same. Invalid encryption"

    # 8. Decrypt your encrypted data stream using the same keyring you used on encrypt.
    with open(ciphertext_filename, 'rb') as ct_file, open(decrypted_filename, 'wb') as pt_file:
        with client.stream(
            mode='d',
            source=ct_file,
            keyring=raw_aes_keyring,
            encryption_context=encryption_context
        ) as decryptor:
            for chunk in decryptor:
                pt_file.write(chunk)

    # 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
    # (This is an example for demonstration; you do not need to do this in your own code.)
    assert filecmp.cmp(plaintext_filename, decrypted_filename), \
        "Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
```