Python용 AWS 암호화 SDK 예제 코드 - AWS 암호화 SDK

문서의 영문과 번역 사이에 충돌이 있는 경우에는 영문 버전을 따릅니다. 번역 버전은 기계 번역을 사용하여 제공합니다.

Python용 AWS 암호화 SDK 예제 코드

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

문자열 암호화 및 해독

다음 예제에서는 AWS 암호화 SDK를 사용하여 문자열을 암호화 및 해독하는 방법을 보여줍니다. 이 예에서는 AWS Key Management Service(AWS KMS)에서 고객 마스터 키(CMK)를 마스터 키로 사용합니다.

""" Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at https://aws.amazon.com/apache-2-0/ or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ from __future__ import print_function import aws_encryption_sdk def cycle_string(key_arn, source_plaintext, botocore_session=None): """Encrypts and then decrypts a string using a KMS customer master key (CMK) :param str key_arn: Amazon Resource Name (ARN) of the KMS CMK (http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html) :param bytes source_plaintext: Data to encrypt :param botocore_session: Existing Botocore session instance :type botocore_session: botocore.session.Session """ # Create a KMS master key provider. kms_kwargs = dict(key_ids=[key_arn]) if botocore_session is not None: kms_kwargs['botocore_session'] = botocore_session master_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kms_kwargs) # Encrypt the plaintext source data. ciphertext, encryptor_header = aws_encryption_sdk.encrypt( source=source_plaintext, key_provider=master_key_provider ) print('Ciphertext: ', ciphertext) # Decrypt the ciphertext. cycled_plaintext, decrypted_header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=master_key_provider ) # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source # plaintext. assert cycled_plaintext == source_plaintext # Verify that the encryption context used in the decrypt operation includes all key pairs from # the encrypt operation. (The SDK can add pairs, so don't require an exact match.) # # In production, always use a meaningful encryption context. In this sample, we omit the # encryption context (no key pairs). assert all( pair in decrypted_header.encryption_context.items() for pair in encryptor_header.encryption_context.items() ) print('Decrypted: ', cycled_plaintext)

바이트 스트림 암호화 및 해독

다음 예제에서는 AWS 암호화 SDK를 사용하여 바이트 스트림을 암호화 및 해독하는 방법을 보여줍니다. 이 예에서는 AWS. 정적, 임시 마스터 키 공급자를 사용합니다.

""" Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at https://aws.amazon.com/apache-2-0/ or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ import filecmp import os import aws_encryption_sdk from aws_encryption_sdk.internal.crypto import WrappingKey from aws_encryption_sdk.key_providers.raw import RawMasterKeyProvider from aws_encryption_sdk.identifiers import WrappingAlgorithm, EncryptionKeyType class StaticRandomMasterKeyProvider(RawMasterKeyProvider): """Randomly and consistently generates 256-bit keys for each unique key ID.""" provider_id = 'static-random' def __init__(self, **kwargs): self._static_keys = {} def _get_raw_key(self, key_id): """Returns a static, randomly-generated symmetric key for the specified key ID. :param str key_id: Key ID :returns: Wrapping key that contains the specified static key :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` """ try: static_key = self._static_keys[key_id] except KeyError: static_key = os.urandom(32) self._static_keys[key_id] = static_key return WrappingKey( wrapping_algorithm=WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING, wrapping_key=static_key, wrapping_key_type=EncryptionKeyType.SYMMETRIC ) def cycle_file(source_plaintext_filename): """Encrypts and then decrypts a file under a custom static master key provider. :param str source_plaintext_filename: Filename of file to encrypt """ # Create a static random master key provider. key_id = os.urandom(8) master_key_provider = StaticRandomMasterKeyProvider() master_key_provider.add_master_key(key_id) ciphertext_filename = source_plaintext_filename + '.encrypted' cycled_plaintext_filename = source_plaintext_filename + '.decrypted' # Encrypt the plaintext source data. with open(source_plaintext_filename, 'rb') as plaintext, open(ciphertext_filename, 'wb') as ciphertext: with aws_encryption_sdk.stream( mode='e', source=plaintext, key_provider=master_key_provider ) as encryptor: for chunk in encryptor: ciphertext.write(chunk) # Decrypt the ciphertext. with open(ciphertext_filename, 'rb') as ciphertext, open(cycled_plaintext_filename, 'wb') as plaintext: with aws_encryption_sdk.stream( mode='d', source=ciphertext, key_provider=master_key_provider ) as decryptor: for chunk in decryptor: plaintext.write(chunk) # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source # plaintext. assert filecmp.cmp(source_plaintext_filename, cycled_plaintext_filename) # Verify that the encryption context used in the decrypt operation includes all key pairs from # the encrypt operation. # # In production, always use a meaningful encryption context. In this sample, we omit the # encryption context (no key pairs). assert all( pair in decryptor.header.encryption_context.items() for pair in encryptor.header.encryption_context.items() ) return ciphertext_filename, cycled_plaintext_filename

여러 마스터 키 공급자로 바이트 스트림 암호화 및 해독

다음 예제에서는 두 개 이상의 마스터 키 공급자와 함께 AWS 암호화 SDK를 사용하는 방법을 보여줍니다. 둘 이상의 마스터 키 공급자를 사용하면 하나의 마스터 키 공급자를 해독에 사용할 수 없는 경우 중복성이 생성됩니다. 이 예에서는 AWS KMS 고객 마스터 키(CMK) 및 RSA 키 페어를 마스터 키로 사용합니다.

""" Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at https://aws.amazon.com/apache-2-0/ or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ import filecmp import os import aws_encryption_sdk from aws_encryption_sdk.internal.crypto import WrappingKey from aws_encryption_sdk.key_providers.raw import RawMasterKeyProvider from aws_encryption_sdk.identifiers import WrappingAlgorithm, EncryptionKeyType from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa class StaticRandomMasterKeyProvider(RawMasterKeyProvider): provider_id = 'static-random' def __init__(self, **kwargs): self._static_keys = {} def _get_raw_key(self, key_id): """Returns a static, randomly generated, RSA key for the specified key ID. :param str key_id: User-defined ID for the static key :returns: Wrapping key that contains the specified static key :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` """ try: static_key = self._static_keys[key_id] except KeyError: private_key = rsa.generate_private_key( public_exponent=65537, key_size=4096, backend=default_backend() ) static_key = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) self._static_keys[key_id] = static_key return WrappingKey( wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA1_MGF1, wrapping_key=static_key, wrapping_key_type=EncryptionKeyType.PRIVATE ) def cycle_file(key_arn, source_plaintext_filename, botocore_session=None): """Encrypts and then decrypts a file using a KMS master key provider and a custom static master key provider. Both master key providers are used to encrypt the plaintext file, so either one alone can decrypt it. :param str key_arn: Amazon Resource Name (ARN) of the KMS Customer Master Key (CMK) (http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html) :param str source_plaintext_filename: Filename of file to encrypt :param botocore_session: existing botocore session instance :type botocore_session: botocore.session.Session """ # "Cycled" means encrypted and then decrypted ciphertext_filename = source_plaintext_filename + '.encrypted' cycled_kms_plaintext_filename = source_plaintext_filename + '.kms.decrypted' cycled_static_plaintext_filename = source_plaintext_filename + '.static.decrypted' # Create a KMS master key provider kms_kwargs = dict(key_ids=[key_arn]) if botocore_session is not None: kms_kwargs['botocore_session'] = botocore_session kms_master_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kms_kwargs) # Create a static master key provider and add a master key to it static_key_id = os.urandom(8) static_master_key_provider = StaticRandomMasterKeyProvider() static_master_key_provider.add_master_key(static_key_id) # Create a master key provider that includes the KMS and static master key providers kms_master_key_provider.add_master_key_provider(static_master_key_provider) # Encrypt plaintext with both KMS and static master keys with open(source_plaintext_filename, 'rb') as plaintext, open(ciphertext_filename, 'wb') as ciphertext: with aws_encryption_sdk.stream( source=plaintext, mode='e', key_provider=kms_master_key_provider ) as encryptor: for chunk in encryptor: ciphertext.write(chunk) # Decrypt the ciphertext with only the KMS master key with open(ciphertext_filename, 'rb') as ciphertext, open(cycled_kms_plaintext_filename, 'wb') as plaintext: with aws_encryption_sdk.stream( source=ciphertext, mode='d', key_provider=aws_encryption_sdk.KMSMasterKeyProvider(**kms_kwargs) ) as kms_decryptor: for chunk in kms_decryptor: plaintext.write(chunk) # Decrypt the ciphertext with only the static master key with open(ciphertext_filename, 'rb') as ciphertext, open(cycled_static_plaintext_filename, 'wb') as plaintext: with aws_encryption_sdk.stream( source=ciphertext, mode='d', key_provider=static_master_key_provider ) as static_decryptor: for chunk in static_decryptor: plaintext.write(chunk) # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source # plaintext. assert filecmp.cmp(source_plaintext_filename, cycled_kms_plaintext_filename) assert filecmp.cmp(source_plaintext_filename, cycled_static_plaintext_filename) # Verify that the encryption context in the decrypt operation includes all key pairs from the # encrypt operation. # # In production, always use a meaningful encryption context. In this sample, we omit the # encryption context (no key pairs). assert all( pair in kms_decryptor.header.encryption_context.items() for pair in encryptor.header.encryption_context.items() ) assert all( pair in static_decryptor.header.encryption_context.items() for pair in encryptor.header.encryption_context.items() ) return ciphertext_filename, cycled_kms_plaintext_filename, cycled_static_plaintext_filename

데이터 키 캐싱을 사용하여 메시지 암호화

다음 예제에서는 Python용 AWS 암호화 SDK의 데이터 키 캐싱의 사용법을 보여줍니다. 이 페이지는 로컬 캐시 (LocalCryptoMaterialsCache)에 필요한 용량 값과 암호화 자료 관리자 캐싱 (캐싱 CMM) 캐시 보안 임계값.

이 기본 예제는 고정 문자열을 암호화하는 함수를 만듭니다. 이 함수를 사용하여 AWS KMS 고객 마스터 키, 필요한 캐시 크기(용량), 최대 수명 값을 지정할 수 있습니다. 데이터 키 캐싱의 보다 복잡한 실제 예제는 를 참조하십시오. Python 데이터 키 캐싱 예제.

선택 사항이지만 이 예제에서는 암호화 컨텍스트 추가 인증 데이터로 사용됩니다. 암호화 컨텍스트로 암호화된 데이터의 암호를 해독할 때는 일반 텍스트 데이터를 발신자에게 반환하기 전에 애플리케이션에서 암호화 컨텍스트가 예상한 것인지 확인해야 합니다. 암호화 컨텍스트는 암호화 또는 암호 해독 작업의 모범 사례 요소이지만 데이터 키 캐싱에서 특별한 역할을 합니다. 자세한 내용은 다음을 참조하십시오. 암호화 컨텍스트: 캐시 항목을 선택하는 방법.

# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You # may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file is # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. """Example of encryption with data key caching.""" import aws_encryption_sdk def encrypt_with_caching(kms_cmk_arn, max_age_in_cache, cache_capacity): """Encrypts a string using an AWS KMS customer master key (CMK) and data key caching. :param str kms_cmk_arn: Amazon Resource Name (ARN) of the KMS customer master key :param float max_age_in_cache: Maximum time in seconds that a cached entry can be used :param int cache_capacity: Maximum number of entries to retain in cache at once """ # Data to be encrypted my_data = "My plaintext data" # Security thresholds # Max messages (or max bytes per) data key are optional MAX_ENTRY_MESSAGES = 100 # Create an encryption context encryption_context = {"purpose": "test"} # Create a master key provider for the KMS customer master key (CMK) key_provider = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[kms_cmk_arn]) # Create a local cache cache = aws_encryption_sdk.LocalCryptoMaterialsCache(cache_capacity) # Create a caching CMM caching_cmm = aws_encryption_sdk.CachingCryptoMaterialsManager( master_key_provider=key_provider, cache=cache, max_age=max_age_in_cache, max_messages_encrypted=MAX_ENTRY_MESSAGES, ) # When the call to encrypt data specifies a caching CMM, # the encryption operation uses the data key cache specified # in the caching CMM encrypted_message, _header = aws_encryption_sdk.encrypt( source=my_data, materials_manager=caching_cmm, encryption_context=encryption_context ) return encrypted_message