def run_raw_provider_check(log_capturer, encrypt_param_name, encrypting_provider, decrypt_param_name, decrypting_provider): log_capturer.set_level(logging.DEBUG) encrypt_kwargs = {encrypt_param_name: encrypting_provider} decrypt_kwargs = {decrypt_param_name: decrypting_provider} encrypt_result = aws_encryption_sdk.encrypt( source=VALUES["plaintext_128"], encryption_context=VALUES["encryption_context"], frame_length=0, **encrypt_kwargs) decrypt_result = aws_encryption_sdk.decrypt(source=encrypt_result.result, **decrypt_kwargs) if isinstance(encrypting_provider, Keyring): trace_entries = (entry for entry in encrypt_result.keyring_trace if ( entry.wrapping_key.provider_id == encrypting_provider.key_namespace and entry.wrapping_key.key_info == encrypting_provider.key_name)) assert trace_entries assert decrypt_result.result == VALUES["plaintext_128"] assert_key_not_logged(encrypting_provider, log_capturer.text) if isinstance(decrypting_provider, Keyring): trace_entries = (entry for entry in decrypt_result.keyring_trace if ( entry.wrapping_key.provider_id == decrypting_provider.key_namespace and entry.wrapping_key.key_info == decrypting_provider.key_name)) assert trace_entries
def encryptionSDKDemo(): import aws_encryption_sdk # # AWS Encryption SDK works with arbitrary length text # plaintext = 'This is a very long text document' # # The MKP object contains reference to master keys # mkp = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[MASTER_KEY_ARN]) encryption_context = {'data_type': 'example', 'classification': 'public'} # # Let's encrypt the plaintext data # ciphertext, encryptor_header = aws_encryption_sdk.encrypt( source=plaintext, key_provider=mkp, encryption_context=encryption_context) # # Let's decrypt the ciphertext data # decrypted_plaintext, decryptor_header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=mkp) print(decrypted_plaintext.decode('utf-8'))
def cycle_string(key_arn, source_plaintext, botocore_session=None): """Encrypts and then decrypts a string under a KMS customer master key (CMK) :param str key_arn: Amazon Resource Name (Arn) of the KMS CMK :param bytes source_plaintext: Data to encrypt :param botocore_session: existing botocore session instance :type botocore_session: botocore.session.Session """ # Create the 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 source plaintext 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) # Validate that the cycled plaintext is identical to the source plaintext assert cycled_plaintext == source_plaintext # Validate that the encryption context used by the decryptor has all the key-pairs from the encryptor assert all(pair in decrypted_header.encryption_context.items() for pair in encryptor_header.encryption_context.items()) print('Decrypted: ', cycled_plaintext)
def EncryptionSdkDemo(): 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 data" encryptionContext = {'type': 'password', 'env': 'dev'} # SDK kullanarak bizim icin olusturulan datakey ile ciphertextimizi elde ediyoruz. cipherText, encryption_header = aws_encryption_sdk.encrypt( source=plainText, encryption_context=encryptionContext, key_provider=kms_key_provider) # print("Encrypted data= ", base64.b64encode(cipherText)) print("Encrypt edildi") decryptedText, decryption_header = aws_encryption_sdk.decrypt( source=cipherText, key_provider=kms_key_provider) # Encryption contextimiz decryption_header icerisinde. print(decryption_header.encryption_context) print('Decrypted Text= ', decryptedText) assert plainText == decryptedText
def retrieve( self, pointer_key: str, expected_context_keys: Set[str] = set(), expected_context: Dict[str, str] = {}, ) -> DocumentBundle: item = self._get_pointer_item(PointerQuery.from_key(pointer_key)) encrypted_data = self._get_object(item) plaintext, header = aws_encryption_sdk.decrypt( source=encrypted_data, key_provider=self.master_key_provider) # ENCRYPTION-CONTEXT-COMPLETE: Making Assertions if not expected_context_keys <= header.encryption_context.keys(): error_msg = ("Encryption context assertion failed! " f"Expected all these keys: {expected_context_keys}, " f"but got {header.encryption_context}!") raise AssertionError(error_msg) if not expected_context.items() <= header.encryption_context.items(): error_msg = ("Encryption context assertion failed! " f"Expected {expected_context}, " f"but got {header.encryption_context}!") raise AssertionError(error_msg) # ENCRYPTION-CONTEXT-COMPLETE: Use Encryption Context on Decrypt validatedItem = PointerItem.from_key_and_context( pointer_key, header.encryption_context) return DocumentBundle.from_pointer_and_data(validatedItem, plaintext)
def retrieve( self, pointer_key: str, expected_context_keys: Set[str] = set(), expected_context: Dict[str, str] = {}, ) -> DocumentBundle: """ Retrieves a document from the Document Bucket system. :param pointer_key: the key for the document to retrieve :param expected_context_keys: the set of context keys that document should have :param expected_context: the set of context key-value pairs that document should have :returns: the document, its key, and associated context """ item = self._get_pointer_item(PointerQuery.from_key(pointer_key)) encrypted_data = self._get_object(item) plaintext, header = aws_encryption_sdk.decrypt( source=encrypted_data, key_provider=self.master_key_provider) # ENCRYPTION-CONTEXT-COMPLETE: Making Assertions if not expected_context_keys <= header.encryption_context.keys(): error_msg = ("Encryption context assertion failed! " f"Expected all these keys: {expected_context_keys}, " f"but got {header.encryption_context}!") raise AssertionError(error_msg) if not expected_context.items() <= header.encryption_context.items(): error_msg = ("Encryption context assertion failed! " f"Expected {expected_context}, " f"but got {header.encryption_context}!") raise AssertionError(error_msg) # ENCRYPTION-CONTEXT-COMPLETE: Use Encryption Context on Decrypt validatedItem = PointerItem.from_key_and_context( pointer_key, header.encryption_context) return DocumentBundle.from_pointer_and_data(validatedItem, plaintext)
def decrypt(self, data): ciphertext = base64.b64decode(data) plaintext, header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=self.master_key_provider) return json.loads(plaintext)
def test_counting_master_key_decrypt_vectors(vector): master_key = CountingMasterKey() plaintext, _header = aws_encryption_sdk.decrypt(source=vector.ciphertext, key_provider=master_key) assert plaintext == vector.plaintext
def encrypt_decrypt(key_arn, source_plaintext, botocore_session=None): """Encrypts and then decrypts a string under one KMS customer master key (CMK) with an unsigned algorithm. :param str key_arn: Amazon Resource Name (ARN) of the KMS CMK :param bytes source_plaintext: Data to encrypt :param botocore_session: existing botocore session instance :type botocore_session: botocore.session.Session """ kwargs = dict(key_ids=[key_arn]) if botocore_session is not None: kwargs["botocore_session"] = botocore_session # Create master key provider using the ARN of the key and the session (botocore_session) kms_key_provider = KMSMasterKeyProvider(**kwargs) # Encrypt the plaintext using the AWS Encryption SDK. It returns the encrypted message and the header ciphertext, encrypted_message_header = encrypt( algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA256, source=source_plaintext, key_provider=kms_key_provider) # Decrypt the encrypted message using the AWS Encryption SDK. It returns the decrypted message and the header plaintext, decrypted_message_header = decrypt( source=ciphertext, key_provider=kms_key_provider) # Check if the original message and the decrypted message are the same assert source_plaintext == plaintext # Check if the headers of the encrypted message and decrypted message match assert all(pair in encrypted_message_header.encryption_context.items() for pair in decrypted_message_header.encryption_context.items())
def retrieve( self, pointer_key: str, expected_context_keys: Set[str] = set(), expected_context: Dict[str, str] = {}, ) -> DocumentBundle: """ Retrieves a document from the Document Bucket system. :param pointer_key: the key for the document to retrieve :param expected_context_keys: the set of context keys that document should have :param expected_context: the set of context key-value pairs that document should have :returns: the document, its key, and associated context """ item = self._get_pointer_item(PointerQuery.from_key(pointer_key)) encrypted_data = self._get_object(item) plaintext, header = aws_encryption_sdk.decrypt( source=encrypted_data, key_provider=self.master_key_provider ) # ENCRYPTION-CONTEXT-START: Making Assertions # ENCRYPTION-CONTEXT-START: Use Encryption Context on Decrypt return DocumentBundle.from_data_and_context( plaintext, item.context )
def decrypt(self, encrypted_data): decrypted_data, decryptor_header = aws.decrypt( source = encrypted_data, key_provider = self.kms_key_provider ) return decrypted_data
def decrypt(self, data): master_key = KMSMasterKey(key_id=self.KeyId) decrypted, decrypt_header = aws_encryption_sdk.decrypt( source=self.decode(data), key_provider=master_key) assert set(self.EncryptionContext.items()) <= set( decrypt_header.encryption_context.items()) return decrypted
def cycle_string(key_arn, source_plaintext, botocore_session=None): """Encrypts and then decrypts a string under a KMS customer master key (CMK). :param str key_arn: Amazon Resource Name (ARN) of the KMS CMK :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) # 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())
def decrypt(kms_key_provider, ciphertext): decrypted, decryptor_header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=kms_key_provider ) print(decrypted)
def decrypt_payload(payload, data_key): my_key_provider = MyRawMasterKeyProvider(data_key) my_key_provider.add_master_key("DataKey") decrypted_plaintext, header = aws_encryption_sdk.decrypt( source=payload, materials_manager=aws_encryption_sdk.DefaultCryptoMaterialsManager( master_key_provider=my_key_provider)) return decrypted_plaintext
def decrypt_value(data, prefix, key_provider): if data.startswith(prefix): data = data[len(prefix):] raw_data = base64.b64decode(data) decrypted_plaintext, decryptor_header = aws_encryption_sdk.decrypt( source=raw_data, key_provider=key_provider) return decrypted_plaintext
def run(aws_kms_cmk, source_plaintext): # type: (str, bytes) -> None """Demonstrate configuring an AWS KMS discovery keyring to only work within a single region. :param str aws_kms_cmk: The ARN of an AWS KMS CMK that protects data keys :param bytes source_plaintext: Plaintext to encrypt """ # Prepare your encryption context. # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context encryption_context = { "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", } # Create the keyring that determines how your data keys are protected. encrypt_keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) # Extract the region from the CMK ARN. decrypt_region = aws_kms_cmk.split(":", 4)[3] # Create the AWS KMS discovery keyring that we will use on decrypt. # # The client supplier that we specify here will only supply clients for the specified region. # The keyring only attempts to decrypt data keys if it can get a client for that region, # so this keyring will now ignore any data keys that were encrypted under a CMK in another region. decrypt_keyring = AwsKmsKeyring(is_discovery=True, client_supplier=AllowRegionsClientSupplier( allowed_regions=[decrypt_region])) # Encrypt your plaintext data. ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( source=source_plaintext, encryption_context=encryption_context, keyring=encrypt_keyring) # Demonstrate that the ciphertext and plaintext are different. assert ciphertext != source_plaintext # Decrypt your encrypted data using the AWS KMS discovery keyring. # # You do not need to specify the encryption context on decrypt # because the header of the encrypted message includes the encryption context. decrypted, decrypt_header = aws_encryption_sdk.decrypt( source=ciphertext, keyring=decrypt_keyring) # Demonstrate that the decrypted plaintext is identical to the original plaintext. assert decrypted == source_plaintext # Verify that the encryption context used in the decrypt operation includes # the encryption context that you specified when encrypting. # The AWS Encryption SDK can add pairs, so don't require an exact match. # # In production, always use a meaningful encryption context. assert set(encryption_context.items()) <= set( decrypt_header.encryption_context.items())
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 run(self, name): """Run this test scenario :param str name: Descriptive name for this scenario to use in any logging or errors """ plaintext, _header = aws_encryption_sdk.decrypt(source=self.ciphertext, key_provider=self.master_key_provider) if plaintext != self.plaintext: # TODO: Actually do something here raise Exception("TODO: ERROR MESSAGE")
def test_null_master_key_cycle(): plaintext = b"some super secret plaintext" master_key = NullMasterKey() ciphertext, _header = aws_encryption_sdk.encrypt(source=plaintext, key_provider=master_key) decrypted, _header = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=master_key) assert plaintext != ciphertext assert plaintext == decrypted
def test_decrypt_from_file(plaintext_filename, ciphertext_filename): """Tests decrypt from known good files.""" with open(ciphertext_filename, "rb") as infile: ciphertext = infile.read() with open(plaintext_filename, "rb") as infile: plaintext = infile.read() decrypted_ciphertext, _header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=setup_kms_master_key_provider()) assert decrypted_ciphertext == plaintext
def test_mrcrypt_legacy_compat_cmm(test_case): master_key = KMSMasterKey(key_id=KEY_ID, client=fake_kms_client(test_case.data_key)) cmm = MrcryptLegacyCompatibilityCryptoMaterialsManager( master_key_provider=master_key) plaintext, header = aws_encryption_sdk.decrypt(source=test_case.ciphertext, materials_manager=cmm) assert PLAINTEXT == plaintext assert ['aws-crypto-public-key'] == list(header.encryption_context.keys()) # noqa=E501 subclasses confuses pylint: disable=no-member
def test_decrypt(self): test_plaintext, test_header = aws_encryption_sdk.decrypt(a=sentinel.a, b=sentinel.b, c=sentinel.b) self.mock_stream_encryptor.called_once_with(a=sentinel.a, b=sentinel.b, c=sentinel.b) assert test_plaintext is sentinel.plaintext assert test_header is sentinel.header
def test_encrypt_minimal_source_stream_api(frame_length, wrapping_class): raw_plaintext = exact_length_plaintext(100) plaintext = wrapping_class(io.BytesIO(raw_plaintext)) key_provider = fake_kms_key_provider() ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( source=plaintext, key_provider=key_provider, frame_length=frame_length) decrypted, _decrypt_header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=key_provider) assert raw_plaintext == decrypted
def run(source_plaintext): # type: (bytes) -> None """Demonstrate an encrypt/decrypt cycle using a raw AES keyring. :param bytes source_plaintext: Plaintext to encrypt """ # Prepare your encryption context. # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context encryption_context = { "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", } # Generate a 256-bit (32 byte) AES key to use with your keyring. # # In practice, you should get this key from a secure key management system such as an HSM. key = os.urandom(32) # Create the keyring that determines how your data keys are protected. keyring = RawAESKeyring( # 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. # # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring key_namespace="some managed raw keys", key_name=b"my AES wrapping key", wrapping_key=key, ) # Encrypt your plaintext data. ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( source=source_plaintext, encryption_context=encryption_context, keyring=keyring ) # Demonstrate that the ciphertext and plaintext are different. assert ciphertext != source_plaintext # Decrypt your encrypted data using the same keyring you used on encrypt. # # You do not need to specify the encryption context on decrypt # because the header of the encrypted message includes the encryption context. decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring) # Demonstrate that the decrypted plaintext is identical to the original plaintext. assert decrypted == source_plaintext # Verify that the encryption context used in the decrypt operation includes # the encryption context that you specified when encrypting. # The AWS Encryption SDK can add pairs, so don't require an exact match. # # In production, always use a meaningful encryption context. assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items())
def test_decrypt_oneshot_no_seek_input(): """Test that decrypt can handle an input stream that is not seekable.""" key_provider = fake_kms_key_provider() ciphertext, _header = aws_encryption_sdk.encrypt( source=VALUES["plaintext_128"], key_provider=key_provider, encryption_context=VALUES["encryption_context"] ) ciphertext_no_seek = NoSeekBytesIO(ciphertext) decrypted, _header = aws_encryption_sdk.decrypt(source=ciphertext_no_seek, key_provider=key_provider) assert decrypted == VALUES["plaintext_128"]
def DecryptField(private_key, field_data): # add padding if needed base64 decoding field_data = field_data + '=' * (-len(field_data) % 4) # base64-decode to get binary ciphertext ciphertext = base64.b64decode(field_data) # decrypt ciphertext into plaintext plaintext, header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=sif_private_master_key_provider) return plaintext
def test_decrypt_from_file(plaintext_filename, ciphertext_filename, key_provider): """Tests decrypt from known good files.""" with open(ciphertext_filename, 'rb') as infile: ciphertext = infile.read() with open(plaintext_filename, 'rb') as infile: plaintext = infile.read() decrypted_ciphertext, _header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=key_provider) assert decrypted_ciphertext == plaintext
def decrypt_it(self, cipher_obj): 'decrypt encrypted text' self.set_key_provider() (decrypted_text, decryptor_header) = aes.decrypt(source=cipher_obj['cipher_text'], key_provider=self.key_provider) if cipher_obj['encryptor_header'] != decryptor_header: raise Exception('Encryption headers do not match!!!') return decrypted_text
def test_decrypt(self): test_plaintext, test_header = aws_encryption_sdk.decrypt(a=sentinel.a, b=sentinel.b, c=sentinel.b) self.mock_stream_encryptor.called_once_with(a=sentinel.a, b=sentinel.b, c=sentinel.b) assert test_plaintext is _PLAINTEXT assert test_header == _HEADER assert test_header is not _HEADER
def decrypt(self, encryption_context_key: str, ciphertext: bytes) -> str: plaintext, header = decrypt( source=ciphertext, materials_manager=self.materials_manager, ) return plaintext.decode("utf-8")