Abhi
Abhi

Reputation: 1255

Python Cryptography module to decrypt Client-side Encrypted data in s3

I have a scenario where data inside s3 is client-side encrypted using symmetric key and I want to decrypt data from Lambda.

My understanding of client-side encryption is s3 uses content encryption key(cek) to encrypt the data and adds this cek in encypted form, iv to s3 file metadata. This cek encryption is facilitated by the customer key which is maintained by Odin in my case. Plan to decrypt is to decrypt the cek from the corresponding file metadata and then use that to decrypt actual contents of file.

Here is the aws s3 documentation about the same - https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/package-summary.html

To achieve this, I am using python cryptography module, I am reading s3 metadata to get x-amz-key(cek) and x-amz-iv, decode them(using base64.b64decode) and use cipher decryptor to decrypt the x-amz-key key, then I am using decrypted key to decrypt actual body. However, when I do this, my lambda runs but gives only garbage data which I am unable to consume.

Code snippet -

sym_key = 'ksjbfkjawdhgiua#151' #this is just a made-up symmetric key
print ('sym key ', type(sym_key), sym_key)
bucket_name = '<s3-bucket-name>'
prefix = '<encryted_file_key>'
s3_email = s3.Object(bucket_name, prefix)
meta = s3_email.get()['Metadata']
print ('meta ', type(meta), meta)
encrypted_data = s3_email.get()['Body'].read()
env_key = base64.b64decode(meta['x-amz-key'])
env_iv = base64.b64decode(meta['x-amz-iv'])
print ("Decrypting symmetric key..")
cipher = Cipher(algorithms.AES(sym_key), modes.CBC(env_iv), backend=default_backend())
decryptor = cipher.decryptor()
decrypt_key = decryptor.update(env_key) + decryptor.finalize()
#using below subsetting the decrypt_key to keep AES key to 256 length
decrypt_key = decrypt_key[len(env_iv):]
print ('decrypt_key ', type(decrypt_key), decrypt_key)
#start data decryption
data_cipher = Cipher(algorithms.AES(decrypt_key), modes.CBC(env_iv), default_backend())
data_decryptor = data_cipher.decryptor()
decrypt_txt = data_decryptor.update(encrypted_data) + data_decryptor.finalize()
#prints gives some garbage characters
print ('decrypt_txt ', type(decrypt_txt), decrypt_txt)

I believe this is the right path to decrypt the data but going wrong with the parameters in the function call. Please advice.

Upvotes: 1

Views: 1268

Answers (1)

Abhi
Abhi

Reputation: 1255

Looks like I had to use ECB() mode to decrypt the x-amz-key while creating first ciphercontext object

cipher = Cipher(algorithms.AES(sym_key), modes.ECB(), backend=default_backend())

This solved the problem

Upvotes: 1

Related Questions