0

I'm a bit out to sea on this one, so I was wondering whether anyone could help.

Does anyone know how to use Public Key encryption/decryption, using RSA keys in PEM format?

I can get it to work if I use the private key in both directions, I can get the public key to encrypt, but I don't know how to structure a script to get it to work if I want to use a public key to encrypt and a private key to decrypt. I see there is an example in the Java based version of the SDK, but I can't even figure it out from that.

Can anyone lead me in the right direction?

Some sample code of the encryption process i'm using with a public key:

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 StaticPublicMasterKeyProvider(RawMasterKeyProvider):
    provider_id = 'static-public'

    def __init__(self, **kwargs):
        self._public_keys = {}

    def _get_raw_key(self, key_id):
                
        with open("public_key.pem", "rb") as key_file:
            public_key = key_file.read()
        self._public_keys[key_id] = public_key

        return WrappingKey(
            wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA512_MGF1,
            wrapping_key=public_key,
            wrapping_key_type=EncryptionKeyType.PUBLIC
        )


if __name__ == '__main__':
    
    source_file = r'myfile.jpg'

    source_file_enc = source_file + '.encrypt'    
    
    public_key_id = os.urandom(8)
    master_key_provider = StaticPublicMasterKeyProvider()
    master_key_provider.add_master_key(public_key_id)

    with open(source_file, 'rb') as sf, open(source_file_enc, 'wb') as sfe:
        with aws_encryption_sdk.stream(
            mode='e',
            source=sf,
            key_provider=master_key_provider
        ) as encryptor:
            for chunk in encryptor:
                sfe.write(chunk)

I have reviewed the python examples on AWS and they are using private keys in both directions.

Any help would be greatly appreciated.

EDIT: links to documentation:

AWS Encryption SDK Developers Guide

Python example generating RSA Key but using private key

Java example using RSA Public key

Note: the two examples use multiple key providers, but still incorporate RSA Keys

2
  • I have reviewed the python examples on AWS and they are using private keys in both directions. Very, very, unlikely, unless they are demonstrating both signing and encryption with RSA. As I am not familiar with AWS perhaps you can include links to the documentation and examples. Commented Jun 27, 2020 at 12:57
  • @PresidentJamesK.Polk , I have updated the above with the appropriate links Commented Jun 28, 2020 at 23:13

1 Answer 1

1

OK, I have finally been given the example that I needed. For current context, the current example resides in a feature branch only on github (so caution in the future, as this link may be broken. You may need to search in master to find the example needed):

https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/master_key_provider/multi/aws_kms_with_escrow.py

The guts of it can be described as follows (directly out of the above example):

    # Create the encrypt master key that only has access to the public key.
    escrow_encrypt_master_key = RawMasterKey(
        # The provider ID and key ID are defined by you
        # and are used by the raw RSA master key
        # to determine whether it should attempt to decrypt
        # an encrypted data key.
        provider_id="some managed raw keys",  # provider ID corresponds to key namespace for keyrings
        key_id=b"my RSA wrapping key",  # key ID corresponds to key name for keyrings
        wrapping_key=WrappingKey(
            wrapping_key=public_key_pem,
            wrapping_key_type=EncryptionKeyType.PUBLIC,
            # The wrapping algorithm tells the raw RSA master key
            # 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,
        ),
    )

    # Create the decrypt master key that has access to the private key.
    escrow_decrypt_master_key = RawMasterKey(
        # The key namespace and key name MUST match the encrypt master key.
        provider_id="some managed raw keys",  # provider ID corresponds to key namespace for keyrings
        key_id=b"my RSA wrapping key",  # key ID corresponds to key name for keyrings
        wrapping_key=WrappingKey(
            wrapping_key=private_key_pem,
            wrapping_key_type=EncryptionKeyType.PRIVATE,
            # The wrapping algorithm MUST match the encrypt master key.
            wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
        ),
    )

If needs be, the escrow_encrypt_master_key can be added to a key ring to provide multiple keys to encrypt your payload.

I hope this helps someone in the future.

Thanks

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.