2

I'm trying to decrypt some S3 files that use client side encryption (not by me). I've been given the public and private keys and told RSA is used... but I'm struggling to figure out how to decrypt this file.

My understanding is that it's a 2 step process:

  1. Download the meta data of the file which contains metadata['x-amz-key'] - This is the first key that need to be decrypted using my private key.

  2. Once this is decrypted it produces a new key that I can use to decrypt the actual file?

I'm not really sure how to do this. So far I've tried this (which I think is covering step 1).

Would love some help with this - very confused.

import base64
from Crypto.PublicKey import RSA

key = "-----BEGIN PRIVATE KEY-----\nMAHJKxxxxxxxx\n-----END PRIVATE KEY-----"
rsa_Key =RSA.importKey(key)
raw_cipher_data = envelope_key
second_key = rsa_Key.decrypt(raw_cipher_data)

This then produces something that looks like this:

b"\x15\\xc0\\s'

Even if this is correct... which I suspect it isn't. How would I then go on to decrypt the actual S3 file?

Thanks again.

NEXT STEP

This is as far as I got with it... seems like a reasonable approach and I'm more confident after lots of reading (this post also helped a lot (How To Decrypt AWS Ruby Client-side Encryption in Python).

However, still can't get this working...

from Crypto.Cipher import AES

object_info = s3.head_object(Bucket="xxxx", Key="Secret.txt")

metadata = object_info['Metadata']
envelope_key = base64.b64decode(metadata['x-amz-key'])
envelope_iv = base64.b64decode(metadata['x-amz-iv'])

ENV_KEY_LENGTH = 32

ENCRYPTION_KEY = base64.b64decode(KEY)

key = "-----BEGIN PRIVATE KEY-----\nXXXX\n-----END PRIVATE KEY-----"
rsa_Key =RSA.importKey(key)
envelope_key = rsa_Key.decrypt(envelope_key)[:ENV_KEY_LENGTH]
envelope_iv = rsa_Key.decrypt(envelope_iv)[:ENV_KEY_LENGTH]

decryptor = AES.new(envelope_key, AES.MODE_CBC, envelope_iv)

with open('Desktop/test.txt', 'r') as f:
    f.read()
    secret_de = decryptor.decrypt(f)
    print(secret_de)
Hazzamataza
  • 983
  • 2
  • 12
  • 25

1 Answers1

1

Based on your reference to the metadata fields, I suspect that what you are looking at is an object that was encrypted using an S3 encryption client[1]. While this does mean that it is encrypted and stored in a consistent manner, unfortunately we do not currently have that format and methodology very well documented, and we do not currently have a client for Python. These are both things we are looking to improve in the future, but that doesn't really help you right now.

As much as I hate to push someone away from Python, in this case my first recommendation would be to use one of the existing supported clients that provides this functionality. Based on your description, you would need one that supports RSA key wrap, so from the feature matrix[2], you would need either the Java or Ruby client.

[1] https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingClientSideEncryption.html

[2] https://docs.aws.amazon.com/general/latest/gr/aws_sdk_cryptography.html

mattsb42-aws
  • 276
  • 1
  • 4
  • Thanks for your honest response - very disappointing to see there's no SDK for python. Seems strange when this is often the go to data science language. Thanks for your recommendation, I'll take a look. I'll post where I've got to and perhaps someone can offer some additional support. – Hazzamataza Apr 24 '18 at 20:04
  • Are you looking for a long term solution or an ad-hoc one-time thing? (the wording of the question seemed to indicate the later) – mattsb42-aws Apr 24 '18 at 22:28
  • Yeah, I can see that. It’s actually needed for a long term solution - the intention is to encrypt all data using the Amazon Java SDK (in an android app) before sending to S3. I’ve written a downloader in python so I can run offline analysis on this data - the encryption part is now an added step I need to deal with. – Hazzamataza Apr 25 '18 at 06:48
  • If you don't need ranged gets and you are working in Java or Python (or CLI), our general recommendation these days is to use the AWS Encryption SDK instead of the S3 encryption client. Have you considered that option? I don't think that we have tested the AWS Encryption SDK for Java on Android yet, but in theory it should work and we are open to suggestions on any changes that might be needed. https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html – mattsb42-aws Apr 25 '18 at 08:49