简体   繁体   中英

How to use client side encryption with Python

I am attempting to use client side encryption to encrypt sensitive data before moving it to cloud storage on S3 and moving it over to redshift. I tried using the sample code provided by AWS, and after paling around with it I got it to run without returning an error, however, it isn't doing anything that I can tell because nothing prints as it should.

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: [encryption key]
    (http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html)
    :param bytes source_plaintext: 
    :param botocore_session: Existing botocore session
    :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)

I am new to Python and encryption so I may be missing some of the syntax or just lacking the knowledge of how it works. Is this the best way of using client side encryption with AWS in python? And if so, why does this code not return anything?

UPDATE: I got it to work using a slightly different method

session = botocore.session.get_session()
client = session.create_client('kms', 
                               region_name = 'us-east-1', 
                               aws_access_key_id = '[YOUR ACCESS KEY]', 
                               aws_secret_access_key = '[YOUR SECRET ACCESSKEY]')

key_id = '[KEY ID]'
plaintext='[FILEPATH\FILENAME.CSV]'


ciphertext = kms.encrypt(KeyId=key_id, Plaintext=plaintext)
#decrypt_ciphertext = kms.decrypt(CiphertextBlob = ciphertext['CiphertextBlob'])
print('Ciphertext: ', ciphertext)
#print('Decrypted Ciphertext: ', decrypt_ciphertext)

now it prints but I am not sure how to tell if the data is actually encrypted

That function does not return anything because it contains no return call.

The intention of that function was to demonstrate how to encrypt plaintext using the library and then decrypt the resulting ciphertext message, demonstrating that the cycle resulted in the same plaintext.

If you are using this in practice, you will want half of that cycle at any given time (ie: either encrypt or decrypt but not both).

You may use pycrypto :

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import hashlib
import base64
from Crypto import Random
from Crypto.Cipher import AES


BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]


class AESCipher:

    def __init__( self, key ):
        self.key = hashlib.sha256(key.encode('utf-8')).digest()

    def encrypt( self, raw ):
        raw = pad(raw)
        iv = Random.new().read( AES.block_size )
        cipher = AES.new( self.key, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) )

    def decrypt( self, enc ):
        enc = base64.b64decode(enc)
        iv = enc[:16]
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return unpad(cipher.decrypt( enc[16:] ))


#password
password="mypassword"

#content
global_report="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

#generate cipher
cipher = AESCipher(bytes(password))

#encrypt
encrypted = cipher.encrypt(bytes(global_report))

#show encrypted
print encrypted

#decrypt
decrypted = cipher.decrypt(encrypted)

#show decrypted
print decrypted

Which return:

E6bbNzM3AaWv0AAntzUYYEufaBa7X+6D5grl1yRYMdUQ/YPoSE525YXUsvxpGoXA8PcYPYDmTd8oPPH2tSU1/XeSTAti+n1JvzG7SwfTxAWzbl/4KcRWNNaFBzr0WJQt0zG8UJyWHXVhTJfteovTB+xa8Ugqmg+2y3XAe7EhsVOKzXlxXzWNfNnDLS74k8BsXrsw7Pt3NK9YQpubDFdNFrF58gE+ukoOAWpllV1Ia4W4I4B3m6dWuBlSgIEDaSZSZliUIQvMW/xuf9R5VuD09dVUnHPhv1977bYOyRuxCT2qDKTnxXiwC0pkj7cFRoKFs5qsrsbvJhjEu0m24Onb3FDrQ+PT4rIqh4YOkt+dSDt5n7yn5t5MsqqAppS2dLwH/m961wS1gs8KAX2U6+7JxwfU0fzqy6EQWMAbdUQZRFtNPurk8Kb0kaUmB9tYpZaNfZ4GlVSYpnZ3IgAaXshBp2ZBfW0SSZMO5dmR0fFC0n662Ynv60hUxmjsRJqHNfHav7kkxtoXi+JEVfUsYmT+y9Z7PJaBRa0E/MCzswP+F4vx0kR5DCo3M4oT/gVBTBwYpts7xy7B/1Hg/DwOJq7GbSu1SS0EK3OdRwXz+rtXgykHutA1E8Dk+nIGIs/E0LiQ47sZKx+QXdN8DVgtXukso8MfeesBhnrGMuW19LZyczs2NyJX3jkryupqrdcFcs38bQa9xifLl3hPHS88hS6n648ZUyEaU+Im5xnWaUDHSuHSwCoUuvYj34p/9vhyhvtsq38SXFsjqppreLYEk7cY/w==
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM