I'm currently going about setting up encryption on AWS DynamoDB for individual columns on a table that are deemed sensitive. From my research, I've decided that the best way of doing this is likely with AWS KMS. From this sprouted a (perhaps very basic) question about the fundamental workings of doing this.
The true purpose, I would suppose, of me encrypting this data is to prevent people from accessing my data via a compromised AWS account (and perhaps AWS itself being compromised, but I'd imagine that's secondary). However, if my AWS account is compromised... doesn't the attacker have access to my KMS key (not directly, but the ability to use the API to encrypt and decrypt data?)
This is a really basic question, I'm sure, but I feel like I can't move forward with a hole in my knowledge this big.
The purpose of having KMS is to protect your data while the key is never visible to your application since the key never leaves KMS. You submit data to AWS KMS to be encrypted, or decrypted, under keys that you control. You set usage policies on these keys that determine which users can use them to encrypt and decrypt data. All requests to use these keys are logged in AWS CloudTrail so you can understand who used which key when.
Having KMS makes it impossible for an attacker to get the encryption keys. Even if an attacker get on hold of your AWS Account(Assuming he gets Admin Access and KMS Access) and use KMS to decrypt a message, you will be able to see that through the logs in accessing these keys which is a necessary security steps to identify these threats.
So in general, if you provide least privilege to users(Not allowing everyone to access KMS), while keeping root account safe with MFA, it will be really difficult for an attacker to access KMS.
Related
I am proposing to use AWS KMS to encrypt my database. However by boss challenge me that what if the someone in Amazon staff has access to steal my KMS and decrypt my database.
The information inside the database is very important and cannot take any risk other people can decrypt it.
Is there other solution to solve this issue? to make sure no one can steal the Key?
Should we use some on-prem HSM to store the key instead ?
As the FAQ points out, AWS KMS is designed such that
no one, including AWS employees, can retrieve your plaintext KMS keys from the service.
If you read further down, it also provides links to various articles detailing the specification and design of the KMS. And as you can see from the volumes of these articles, the full scope of design consideration and how it complies with FIPS certification is beyond the scope of this answer.
However, as an example, refer to the cryptographic details tech paper for some ideas of how it works. There are 2 areas mentioned where keys are present:
In the KMS Keys Repository
In the HSM modules
KMS Keys Repository
The repository serves as durable storage for the keys. Keys are, of course, stored encrypted. The article further explains that the key repository leverages on IAM roles.
Only under AWS IAM roles and accounts administered by each customer can customer KMS keys be created, deleted, or used to encrypt, decrypt, sign, or verify data.
This is the same way authentication and authorization to any other AWS services are managed. Hence, this is one way to prevent AWS employees from gaining access to the keys. How IAM works and how it is secured is once again beyond the scope of this answer.
HSM Modules
Unlike the KMS keys repository, the HSM Modules will have access to the plain text keys. However, the plain text keys are only loaded in-memory for the duration that they are used. They are not durably stored in the HSM modules.
These keys are made available only on the HSMs and only in memory for the necessary time needed to process your cryptographic request.
Hence, employees with access to these modules would be able to theoretically gain access to these keys. To mitigate this risk, if you go to the design goals section, the article further explains the modules use quorum-based access controls.
Multiple Amazon employees with role-specific access to quorum-based access controls are required to perform administrative actions on the HSMs.
That is, no single employee will have administrative access to these modules. Multiple employees are always required. Once again, how AWS assigns which roles to which employees at which management level is beyond the scope of this answer.
As the question requested, these are just some of the considerations of how the service is secured against AWS employees. For an organization to make a decision on whether to use AWS, usually it should be based on a comprehensive set of security policies and an audit whether AWS complies to these requirements.
EDIT
Since you mentioned also how to convince stakeholders, this is usually a business question rather than a technical one.
I would refer them to AWS compliance for evidence that AWS goes through rigorous 3rd party audits. Would then point out the security of a system is only as strong as the weakest link. That is, using AWS does not mean we automatically have AWS security. We have to ensure our software, our people, and our processes are secure against exploits. So unless we are sure we have better security profile than AWS (with all their compliance and audits), our focus and worry should be more on securing our resources.
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?
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?
CSE
✅ 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.
I am wondering if you please help me out with the following question.
What are the differences between the KMS and the secret manager in GCP? Thank you in advance.
https://cloud.google.com/secret-manager/docs/
HB
Cloud KMS encrypts data and returns the encrypted ciphertext. Cloud KMS does not store the secret, only the keys to encrypt/decrypt.
Secret Manager actually stores the secret material. Secret Manager also keeps a history (versions) of secret material. All data in Secret Manager is encrypted. By default, it is encrypted with a Google-managed key. You can actually use Cloud KMS to encrypt Secret Manager secrets (this is called "CMEK"), in which case the user controls the keys.
Cloud KMS is designed as a cryptographic oracle system: nobody, including yourself, can get the keys out: this means they're locked inside the system and you don't have to worry in practice about them leaking. The tradeoff is that the only thing you can do with those keys is encrypt, decrypt, and other cryptographic operations: useful for protecting data, or even for encrypting secrets, but if you have a database password or something else which you want to keep secret, but then actually be able to use or send elsewhere, you have to store the encrypted version, then use Cloud KMS to decrypt it.
When you do have configuration info like a database password, where your software actually needs the secret, not cryptographic operations, then Secret Manager is designed for that use case. The tradeoff is that if you get a copy of the secret out, it's harder to keep it from leaking and be certain it's controlled.
Thanks for using GCP!
Has anybody tried to use AWS KMS on Heroku?
On one hand, Heroku runs on AWS, so presumably it should work.
On other hand, I haven't seen any references that it was used in Heroku.
My main goal is to be able to get an encryption key from a hardware secure module (vs hardcoding it in my code or putting it in an environmental variable).
There is no reason why you should not be able to call a KMS endpoint from anywhere you have internet connectivity.
You still need to have an access key and secret access key for the AWS account you are using and that account needs to have permissions on KMS.
You will need to distribute the encrypted stuff and the aws keys to your Heroku instance. You can then decrypt and use KMS from there.
One thing that it worth mentioning: when using KMS you never see the actual key KMS uses. You can create the key, you can encrypt and decrypt, and/or you can have permissions on the specific API operations, but you cannot get the plaintext key.
What you normally do is some sort of envelope encryption in which you generate your own key and encrypt it via KMS and send the encrypted key and the encrypted data to the destination.
I'm working with AppSync on a project, and will be capturing relatively sensitive user data which will require encryption at rest in a database.
Currently, I am building with DynamoDB resolvers after a mutation or query, but happy to explore other solutions (such as encrypting with KMS through a Lambda function and then sending to DynamoDB; or using DynamoDB Streams to refactor the data once a new entry is created in a table?)
The KMS would be managed through IAM, with user's assigned through a Cognito user pool (I'm quite new to this, but believe that's the best approach).
this all depends on who you are protecting the data from. if the decrypt is going to actually happen in AWS, then AWS has the decrypt key at least temporarily (because you let them manage the keys, and give them to ciphers that reside in AWS). you can assume that AWS are trusted to forget the key and the decrypted plaintext ASAP, and not backdoor your decrypts. if you are only worried about third-parties (ie: not-AWS) getting in, then this is ok. Just keep in mind that your defenses against the cloud provider if you do not do end-to-end are limited.
If you are actually worried about AWS decrypting your stuff, there are a few major issues, because that demands end-to-end encryption to handle: decrypts would have to happen outside of AWS (ie: decrypt on a phone or a program that runs on a user's laptop), which implies that keys themselves are only decrypted outside of AWS, and if you search data you are not telling AWS what you are searching for (ie: angry-protesters-on-my-last-visit.mp4). The latter is possible do to, but there are very few general purpose products that even attempt to do correct end-to-end encryption.
DynamoDB now supports encryption at rest, you can enable it on your table.