def sample_raw_rsa_keyring_using_different_wrapping_algorithm(): for alg in WrappingAlgorithm: if alg.encryption_type is EncryptionType.ASYMMETRIC: yield RawRSAKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_algorithm=alg, private_wrapping_key=_PRIVATE_WRAPPING_KEY, public_wrapping_key=_PUBLIC_WRAPPING_KEY, ) pem_and_der_encoded_raw_rsa_keyring = [ RawRSAKeyring.from_pem_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, private_encoded_key= _RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITHOUT_PASSWORD, public_encoded_key=_RAW_RSA_PUBLIC_KEY_PEM_ENCODED, wrapping_algorithm=_WRAPPING_ALGORITHM, ), RawRSAKeyring.from_pem_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, private_encoded_key=_RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITH_PASSWORD, public_encoded_key=_RAW_RSA_PUBLIC_KEY_PEM_ENCODED, password=b"mypassword", wrapping_algorithm=_WRAPPING_ALGORITHM, ), RawRSAKeyring.from_pem_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, public_encoded_key=_RAW_RSA_PUBLIC_KEY_PEM_ENCODED, wrapping_algorithm=_WRAPPING_ALGORITHM, ), RawRSAKeyring.from_der_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, private_encoded_key= _RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITHOUT_PASSWORD, public_encoded_key=_RAW_RSA_PUBLIC_KEY_DER_ENCODED, wrapping_algorithm=_WRAPPING_ALGORITHM, ), RawRSAKeyring.from_der_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, private_encoded_key=_RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITH_PASSWORD, public_encoded_key=_RAW_RSA_PUBLIC_KEY_DER_ENCODED, password=b"mypassword", wrapping_algorithm=_WRAPPING_ALGORITHM, ), RawRSAKeyring.from_der_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, public_encoded_key=_RAW_RSA_PUBLIC_KEY_DER_ENCODED, wrapping_algorithm=_WRAPPING_ALGORITHM, ), ] for keyring in pem_and_der_encoded_raw_rsa_keyring: yield keyring
def test_raw_master_key_decrypts_what_raw_keyring_encrypts( encryption_materials_samples): test_raw_rsa_keyring = RawRSAKeyring.from_pem_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_algorithm=_WRAPPING_ALGORITHM, private_encoded_key=_PRIVATE_WRAPPING_KEY_PEM, public_encoded_key=_PUBLIC_WRAPPING_KEY_PEM, ) # Creating an instance of a raw master key test_raw_master_key = RawMasterKey( key_id=_KEY_ID, provider_id=_PROVIDER_ID, wrapping_key=WrappingKey( wrapping_algorithm=_WRAPPING_ALGORITHM, wrapping_key=_PRIVATE_WRAPPING_KEY_PEM, wrapping_key_type=EncryptionKeyType.PRIVATE, ), ) # Call on_encrypt function for the keyring encryption_materials = test_raw_rsa_keyring.on_encrypt( encryption_materials=encryption_materials_samples) # Check if plaintext data key encrypted by raw keyring is decrypted by raw master key raw_mkp_decrypted_data_key = test_raw_master_key.decrypt_data_key_from_list( encrypted_data_keys=encryption_materials._encrypted_data_keys, algorithm=encryption_materials.algorithm, encryption_context=encryption_materials.encryption_context, ).data_key assert encryption_materials.data_encryption_key.data_key == raw_mkp_decrypted_data_key
def raw_rsa_keyring(): return RawRSAKeyring.from_pem_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1, private_encoded_key=VALUES["private_rsa_key_bytes"][1], )
def ephemeral_raw_rsa_keyring( size=4096, wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1): # type: (int, WrappingAlgorithm) -> RawRSAKeyring key_bytes = _generate_rsa_key_bytes(size) return RawRSAKeyring.from_pem_encoding( key_namespace="fake", key_name="rsa-{}".format(size).encode("utf-8"), wrapping_algorithm=wrapping_algorithm, private_encoded_key=key_bytes, )
def test_raw_keyring_decrypts_what_raw_master_key_encrypts( encryption_materials_samples): # Create instance of raw master key test_raw_master_key = RawMasterKey( key_id=_KEY_ID, provider_id=_PROVIDER_ID, wrapping_key=WrappingKey( wrapping_algorithm=_WRAPPING_ALGORITHM, wrapping_key=_PRIVATE_WRAPPING_KEY_PEM, wrapping_key_type=EncryptionKeyType.PRIVATE, ), ) test_raw_rsa_keyring = RawRSAKeyring.from_pem_encoding( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_algorithm=_WRAPPING_ALGORITHM, private_encoded_key=_PRIVATE_WRAPPING_KEY_PEM, public_encoded_key=_PUBLIC_WRAPPING_KEY_PEM, ) raw_mkp_generated_data_key = test_raw_master_key.generate_data_key( algorithm=encryption_materials_samples.algorithm, encryption_context=encryption_materials_samples.encryption_context, ) raw_mkp_encrypted_data_key = test_raw_master_key.encrypt_data_key( data_key=raw_mkp_generated_data_key, algorithm=encryption_materials_samples.algorithm, encryption_context=encryption_materials_samples.encryption_context, ) decryption_materials = test_raw_rsa_keyring.on_decrypt( decryption_materials=DecryptionMaterials( algorithm=encryption_materials_samples.algorithm, encryption_context=encryption_materials_samples.encryption_context, verification_key=b"ex_verification_key", ), encrypted_data_keys=[raw_mkp_encrypted_data_key], ) assert raw_mkp_generated_data_key.data_key == decryption_materials.data_encryption_key.data_key
def run(source_plaintext): # type: (bytes) -> None """Demonstrate an encrypt/decrypt cycle using a raw RSA keyring loaded from a PEM-encoded key. :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 an RSA private key to use with your keyring. # In practice, you should get this key from a secure key management system such as an HSM. # # The National Institute of Standards and Technology (NIST) recommends a minimum of 2048-bit keys for RSA. # https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths # # Why did we use this public exponent? # https://crypto.stanford.edu/~dabo/pubs/papers/RSA-survey.pdf private_key = rsa.generate_private_key(public_exponent=65537, key_size=4096, backend=default_backend()) # Serialize the RSA keypair to PEM encoding. # This or DER encoding is likely to be what you get from your key management system in practice. private_key_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption(), ) public_key_pem = private_key.public_key().public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo, ) # Create the keyring that determines how your data keys are protected. # # If your key is encoded using DER, you can use RawRSAKeyring.from_der_encoding keyring = RawRSAKeyring.from_pem_encoding( # The key namespace and key name are defined by you # and are used by the raw RSA 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-rsa-keyring key_namespace="some managed raw keys", key_name=b"my RSA wrapping key", private_encoded_key=private_key_pem, public_encoded_key=public_key_pem, # The wrapping algorithm tells the raw RSA keyring # how to use your wrapping key to encrypt data keys. # # We recommend using RSA_OAEP_SHA256_MGF1. # You should not use RSA_PKCS1 unless you require it for backwards compatibility. wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1, ) # 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())