I have an application that will be used for handling some highly sensitive documents.
The intent is to upload these documents to S3 via my app. The documents would only ever be retrieved by my app as well, on an as-needed basis.
As I've been reading, S3 offers server-side encryption (SSE), where data is transparently encrypted and decrypted on upload/download respectively.
That being the case, this seems like any misconfiguration I make of my S3 bucket, or if my AWS credentials are compromised, an attacker would have access to all of my sensitive data in S3. I know I should make sure not to misconfigure S3 and safeguard my credentials, but I also know that things happen.
Basically, from what I can tell, Server Side encryption is really a "check the box" type option that allows you to say that you have encryption at rest, but doesn't protect you from the most common S3 data leakages (bucket misconfiguration and compromised creds).
Getting to the point, it seems like client-side encryption is my best option. That said, I haven't read about a lot of good options for managing the keys used to encrypt my data on the client-side, throughout the data lifecycle.
My questions are
- Do I understand server-side encryption correctly?
- Would client-side would be my most secure option?
- What strategies/tools do you recommend for managing keys when using client-side encryption?
CodePudding user response:
TLDR:
CSE is practically the most secure way for storing data in S3, granted you can keep your key(s) safe.
Using CSE, Amazon themselves are guaranteed to never have had access to the private key(s) as opposed to SSE & can't view/share your data at any time e.g. when forced to via subpoenas.
For educational purposes, the most secure way theoretically would be 2 combined layers of encryption of CSE SSE-KMS. This should only be used in extreme cases but it's ultimately the most secure way to store data in S3.
CSE SSE-S3 also won't cause any harm as SSE-S3 is free of charge.
A more in-depth explanation:
Do I understand server-side encryption correctly?
Yes in that server-side encryption (SSE) allows you to have encryption at rest.
However, using SSE doesn't necessarily mean that you cannot be protected from bucket misconfiguration or compromised creds.
There are 3 types of SSE.
They all share the similarity that the encryption & decryption of data is managed by AWS:
- SSE-S3: Server-side encryption with S3-managed keys
- SSE-KMS: Server-side encryption with KMS keys stored in AWS KMS
- SSE-C: S3 server-side encryption with customer-provided encryption keys
SSE-S3
✅ Protects against physical access
❌ Protects against bucket misconfiguration
❌ Protects against leaked credentials
❌ AWS cannot view your data in any circumstance
SSE-S3 ensures that, at a bare minimum, if someone ripped a hard drive out of an AWS data centre that had your data on it, your data would be encrypted.
Any IAM principal with s3:GetObject
access to your object(s) is able to read your object(s) unencrypted so if AWS credentials were leaked that had access to the object, any malicious actor would be able to access the decrypted version of your file.
Using SSE-S3 means that - yes if your bucket is misconfigured or credentials are leaked, a malicious actor can access your un-encrypted data.
But it's not there to safeguard you.
It's more there in practice to allow AWS to comply with security compliance certifications & protect against misuse of Amazon's internal network and/or human security to physical S3 infrastructure (as extremely rare as that may be).
It costs £0.00 to use SSE-S3 & any encryption is better than none.
SSE-KMS
✅ Protects against physical access
✅ Protects against bucket misconfiguration
❌ Protects against leaked credentials
❌ AWS cannot view your data in any circumstance
With SSE-KMS, you have an extra layer of protection - a KMS key - in case you wake up one morning & randomly decide to open up your bucket to the world.
It requires any malicious actors wanting to read or write objects to have access to both the object and the key. You have to misconfigure both your S3 permissions & your KMS key permissions to accidentally grant access, not just S3 permissions as in the case of SSE-S3.
This option, while not being free, would protect against bucket misconfiguration but not compromised creds.
Your bucket can be open but all anyone would get with no access to the KMS key would be encrypted jibberish.
FYI: AWS KMS is designed so that no one, including AWS employees, can retrieve your plaintext keys from the service.
SSE-C
✅ Protects against physical access
✅ Protects against bucket misconfiguration
✅ Protects against leaked credentials
❓ AWS cannot view your data in any circumstance1
SSE-C protects against bucket misconfiguration & compromised AWS creds.
You manage your own keys & S3 manages the encryption and decryption process. You do need to provide an encryption key as part of your request, but you don’t need to write any code to perform object encryption or decryption.
In this case, nobody has the key to unlock the files other than you.
Your bucket could be open to anyone & your credentials could be leaked for anyone to be able to get an object. But if you're the only one with the key needed for unlocking the file, all anyone could get is encrypted gibberish.
While this SSE option keeps you safe against bucket misconfiguration & compromised creds, you're now also responsible for securing your creds, bucket and your key (which is arguably a larger attack vector).
1 Technically, Amazon has had access to your key at some point as you've sent it to them but according to the docs, Amazon S3 does not store the encryption key you provide. Obviously, S3 source code is not open source and we cannot 100% guarantee this. I would be very surprised if AWS was lying as it would affect their reputation but for the sake of correctness, I will mark this down as uncertain.
Would client-side be my most secure option?
✅ Protects against physical access
✅ Protects against bucket misconfiguration
✅ Protects against leaked credentials
✅ AWS cannot view your data in any circumstance
Client-side encryption (CSE) would be more "secure" than SSE for S3 storage in that you manage everything. You manage the encryption process, the encryption keys, and related tools as opposed to AWS doing it.
You are encrypting objects before they are uploaded to S3 & you are decrypting them after they are downloaded from S3. S3 does not have any knowledge of how you do that and is only storing your files.
You are the weakest (or strongest) link when using CSE but in terms of data security, CSE is more secure than SSE.
What strategies/tools do you recommend for managing keys when using client-side encryption?
This is a very broad question but in relation to S3 CSE, you have 2 options:
- Use a key stored in AWS Key Management Service (AWS KMS)
- Use a key that you store (& retrieve) within your application
Which option to go with depends on how much you trust AWS.
The answer on which method(s) to use depends on the sensitivity of your files & how much you trust AWS and/or your ability in keeping your key(s) secure.