def test_threading_loop_with_common_cache(): """Test thread safety of client while using common cryptographic materials cache across all threads.""" # Check for the CMK ARN first to fail fast if it is not available get_cmk_arn() rounds = 20 cache = aws_encryption_sdk.LocalCryptoMaterialsCache(capacity=40) plaintext_inputs = [ dict(input_value=copy.copy(PLAINTEXT), start_pause=random_pause_time(), cache=cache) for _round in range(rounds) ] ciphertext_values = get_all_thread_outputs( crypto_function=aws_encryption_sdk.encrypt, thread_inputs=plaintext_inputs) ciphertext_inputs = [ dict(input_value=ciphertext, start_pause=random_pause_time(), cache=cache) for ciphertext in ciphertext_values ] decrypted_values = get_all_thread_outputs( crypto_function=aws_encryption_sdk.decrypt, thread_inputs=ciphertext_inputs) assert all(value == PLAINTEXT for value in decrypted_values)
def test_encryption_cycle_with_caching(): algorithm = Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 frame_length = 1024 key_provider = fake_kms_key_provider(algorithm.kdf_input_len) cache = aws_encryption_sdk.LocalCryptoMaterialsCache(capacity=10) ccmm = aws_encryption_sdk.CachingCryptoMaterialsManager( master_key_provider=key_provider, cache=cache, max_age=3600.0, max_messages_encrypted=5 ) encrypt_kwargs = dict( source=VALUES["plaintext_128"], materials_manager=ccmm, encryption_context=VALUES["encryption_context"], frame_length=frame_length, algorithm=algorithm, ) encrypt_cache_key = build_encryption_materials_cache_key( partition=ccmm.partition_name, request=EncryptionMaterialsRequest( encryption_context=VALUES["encryption_context"], frame_length=frame_length, algorithm=algorithm, plaintext_length=len(VALUES["plaintext_128"]), ), ) ciphertext, header = aws_encryption_sdk.encrypt(**encrypt_kwargs) decrypt_cache_key = build_decryption_materials_cache_key( partition=ccmm.partition_name, request=DecryptionMaterialsRequest( algorithm=algorithm, encrypted_data_keys=header.encrypted_data_keys, encryption_context=header.encryption_context, ), ) assert len(cache._cache) == 1 assert cache._cache[encrypt_cache_key].messages_encrypted == 1 assert cache._cache[encrypt_cache_key].bytes_encrypted == 128 _, _ = aws_encryption_sdk.decrypt(source=ciphertext, materials_manager=ccmm) assert len(cache._cache) == 2 assert decrypt_cache_key in cache._cache _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) assert len(cache._cache) == 2 assert cache._cache[encrypt_cache_key].messages_encrypted == 4 assert cache._cache[encrypt_cache_key].bytes_encrypted == 512 _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) assert len(cache._cache) == 2 assert cache._cache[encrypt_cache_key].messages_encrypted == 2 assert cache._cache[encrypt_cache_key].bytes_encrypted == 256
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"} # Set up an encryption client with an explicit commitment policy. Note that if you do not explicitly choose a # commitment policy, REQUIRE_ENCRYPT_REQUIRE_DECRYPT is used by default. client = aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT) # Create a master key provider for the KMS customer master key (CMK) key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(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 = client.encrypt( source=my_data, materials_manager=caching_cmm, encryption_context=encryption_context ) return encrypted_message
def build_crypto_materials_manager_from_args(key_providers_config, caching_config): # type:(List[RAW_MASTER_KEY_PROVIDER_CONFIG], CACHING_CONFIG) -> aws_encryption_sdk.CachingCryptoMaterialsManager """Builds a cryptographic materials manager from the provided arguments. :param list key_providers_config: List of one or more dicts containing key provider configuration :param dict caching_config: Parsed caching configuration :rtype: aws_encryption_sdk.materials_managers.base.CryptoMaterialsManager """ caching_config = copy.deepcopy(caching_config) key_provider = _parse_master_key_providers_from_args(*key_providers_config) cmm = aws_encryption_sdk.DefaultCryptoMaterialsManager(key_provider) if caching_config is None: return cmm cache = aws_encryption_sdk.LocalCryptoMaterialsCache( capacity=caching_config.pop("capacity")) return aws_encryption_sdk.CachingCryptoMaterialsManager( backing_materials_manager=cmm, cache=cache, **caching_config)
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 master key key_provider = aws_encryption_sdk.KMSMasterKeyProvider( key_ids=[kms_cmk_arn]) # Create a 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 encryptData specifies a caching CMM, # the encryption operation uses the data key cache encrypted_message, _header = aws_encryption_sdk.encrypt( source=my_data, materials_manager=caching_cmm, encryption_context=encryption_context) return encrypted_message
def EncryptionSdkCacheDemo(): session = botocore.session.Session(profile=PROFILE_NAME) kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider( botocore_session=session, key_ids=[MASTER_KEY_ARN], region_names=[REGION]) plainText = b"This is my secret data12" encryptionContext = {'type': 'password', 'env': 'dev'} # Create a local cache cache = aws_encryption_sdk.LocalCryptoMaterialsCache(10) # Create a caching CMM caching_cmm = aws_encryption_sdk.CachingCryptoMaterialsManager( master_key_provider=kms_key_provider, cache=cache, max_age=600.0, max_messages_encrypted=10, ) # SDK kullanarak bizim icin olusturulan datakey ile ciphertextimizi elde ediyoruz. cipherText, encryption_header = aws_encryption_sdk.encrypt( source=plainText, encryption_context=encryptionContext, materials_manager=caching_cmm) # print("Encrypted data= ", base64.b64encode(cipherText)) decryptedText, decryption_header = aws_encryption_sdk.decrypt( source=cipherText, materials_manager=caching_cmm) # Encryption contextimiz decryption_header icerisinde. # print(decryption_header.encryption_context) print('Decrypted Text= ', decryptedText) assert plainText == decryptedText