AWS S3 SSE : s3 managed keys encrypted object upload using python - amazon-web-services

I am simply trying to upload encrypted object to S3 bucket.
I have gone through the AWS documentation on SSE.
Most confusing part is I am not clear on :
1. If we need to set default server side encryption option to AES256(I am assuming it is S3 managed key) for bucket before uploading object to s3
or
2. we can directly upload to s3 bucket without having any server side encryption option set for that bucket?
Assuming second point true, I have tried to upload object on S3 specifying extra arguments:
s3_con.upload_file('abc.txt','s3_key_path/abc.txt',ExtraArgs={"ServerSideEncryption": "AES256"})
I was able to upload file using above code line but the file was not encrypted.
So I guess I need to try first point before uploading to bucket.
How can I upload encrypted object using server side encryption using S3 managed key in python and what steps I need to do for this?

The file is encrypted. Look at the Properties > Encryption tab in the AWS console for that S3 object.
You can see the contents because SSE-S3 (AES-256) is transparent at-rest encryption. S3 encrypts the object as it's written to disk, and decrypts it as it's read from disk. Because you have permission to get the object, that process is transparent to you.
You also have other encryption options including KMS managed keys, your own managed keys, and doing client-side encryption prior to sending to S3.

Related

Encryption of s3 object

I am storing data in file in aws s3 and already enabled SSE. but i am curious to know is there a way to encrypt the data so when someone download the file so they cant see the content?? I am just new to AWS and it would be great if somw one give the input
Use the AWS Key Management Service (AWS KMS) to encrypt the data prior to uploading it to an Amazon S3 bucket. Then the data will remain encrypted until it's decrypted using the key. YOu can find an example here (for Java SDK)
https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/KMSEncryptionExample.java
already enabled SSE.
SSE encrypts the content on S3, but an authenticated client cloud access the content in plain, the encryption is done under the hood and the client is unable to access the ciphertext (encrypted form)
You can use the default s3 key or a custom KMS key (CMS) , where the client need explicit access to decrypt the content.
download the file so they cant see the content??
Then the content needs to be encrypted before the upload. AWS provides some support for the client-side encryption but the client is free to implement its own encryption strategy and the key management.
To solve trouble with managing the keys on the client side, it's often more practical to stick with SSE and allow access to S3 or the used CMS (key) only to identities that must access the content.

Ensure data is not lost during AWS S3 sync

I need to copy all contents of an S3 bucket to another S3 bucket. Planning to use s3 sync.
aws s3 sync s3://sourcebucket s3://destinationbucket
After this process, is there any way to verify if all data is migrated to the new bucket? (i.e no data is missed or lost)
Or is there any guarantee that data will not be lost (specified anywhere in official doc?)?
Assuming you want this verification done after the sync is terminated. S3 provides MD5 hash of objects as ETag. You can traverse through your local directory making sure that object does exists in the S3 bucket and integrity can be verified by comparing the local and remote MD5 hashes.
(https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html#RESTObjectGET-responses)

Aws S3 etag not matching md5 after KMS encryption

All- We are working on migrating some confidential & regulatory information from Local UNIX file system to S3.
The files are copied using AWS EC2 instance into S3 using "aws s3 cp--sse aws:kms --sse-kms-key-id....... " command.
What i have noticed is the etag is different from the unix md5sum. It is exactly the same if i don't encrypt the data using kms keys.
I need to validate the upload to make sure data is not corrupt while uploading to S3, how do i validate my file is intact as etag won't match due to encryption.
Any help is really appreciated!
PS: my files are not > 5gb, i am aware of the issue with multipart upload and it is not applicable for me....
In AWS S3 the etag is not an MD5 checksum. If just happens that this is the case in the past but AWS warns not to rely on this method for integrity checks.
In the following link is the text that I am referring to:
The ETag may or may not be an MD5 digest of the object data.
The entity tag is a hash of the object. The ETag reflects changes only
to the contents of an object, not its metadata. The ETag may or may
not be an MD5 digest of the object data. Whether or not it is depends
on how the object was created and how it is encrypted as described
below:
Objects created by the PUT Object, POST Object, or Copy operation, or through the AWS Management Console, and are encrypted by SSE-S3 or
plaintext, have ETags that are an MD5 digest of their object data.
Objects created by the PUT Object, POST Object, or Copy operation, or through the AWS Management Console, and are encrypted by SSE-C or
SSE-KMS, have ETags that are not an MD5 digest of their object data.
If an object is created by either the Multipart Upload or Part Copy operation, the ETag is not an MD5 digest, regardless of the method of
encryption.
Common Response Headers

How to use AWS S3 server side encryption SSE?

Say for example I leave an AWS S3 bucket open to the public.
My goal is that if someone downloads a file from that bucket then what they get is an encrypted file.
I thought SSE-S3 would do this but it does not - it appears that any file downloaded is not encrypted.
So how can I reach my goal of ensuring that files served from S3 are encrypted?
What you are looking for is Protecting Data Using Client-Side Encryption. If you want S3 to serve encrypted files, then you have to save them as encrypted object. You manage encryption/decryption. SSE will store the data after encrypting it and will decrypt it automatically when it is downloaded.
From: Protecting Data Using Encryption
Use Server-Side Encryption – You request Amazon S3 to encrypt your object before saving it on disks in its data centers and decrypt it when you download the objects.
Use Client-Side Encryption – You can encrypt data client-side and upload the encrypted data to Amazon S3. In this case, you manage the encryption process, the encryption keys, and related tools.

AWS S3 server side encryption using CLI

I'm trying to use server side encryption having AWS KMS setup to upload objects to S3.
The documentation says that the uploaded objects should be encrypted;
Server-side encryption is about data encryption at rest—that is,
Amazon S3 encrypts your data at the object level as it writes it to
disks in its data centers and decrypts it for you when you access it.
I've setup KMS master key and trying to use CLI to upload an object in the following way
aws s3api put-object --bucket test --key keys/test.txt --server-side-encryption aws:kms --ssekms-key-id <my_master_Key_id> --body test.txt
The upload succeeds and I see the following response
{
"SSEKMSKeyId": "arn:aws:kms:eu-central-1:<id>:key/<my_master_key>",
"ETag": "\"a4f4fdf078bdd5df758bf81b2d9bc94d\"",
"ServerSideEncryption": "aws:kms"
}
Also when checking the file in S3 I see in details that it has been encrypted server side with a proper master key.
The problem is that when I download the file with a user not having a permission to use the KMS master key, I can open and read the file without a problem, when it should be encrypted.
Note: I also have PutObject policy denying all uploads without server-side encryption, which works fine.
I wonder if I misunderstand the server side encryption, or do I do something wrong? Any help is appreciated.
Unfortunately, I think you misunderstood server-side encryption in S3. Like you pointed yourself, from S3 server-side encryption (SSE) docs:
Server-side encryption is about protecting data at rest.
When S3 receives your object, it calls KMS to create a data key, encrypts your data with that data key (not the master key), and stores the encrypted data key along with the encrypted data.
When you try to download the encrypted files, S3 sees it has been encrypted, asks KMS to decrypt the data key (using the master key), and then uses the decrypted data key to decrypt the data before returning to you. My understanding from the docs and from the way SSE and KMS work is that there is no assumption on the user needing to have access to the master key for that to work -- it suffices that S3 has access to it.
The use case you described is more similar to S3 client-side encryption:
Client-side encryption refers to encrypting data before sending it to
Amazon S3.
In this scenario, the S3 client (instead of S3 on the backend) will ask for a KMS data key (derived from the master key), encrypt data client-side and upload it. It will not be possible to decrypt it on the server, and when clients download the (encrypted) files, decryption needs to happen client-side (the S3 client deals with that for you, though).