Regardless of the format of encryption, what is the best way to store an encryption key on an AWS EC2 server?

I am storing encrypted information in a MySQL database and my cryptography key is stored in code. Data is encoded/decoded using this key when saving/retrieving from the database. Obviously, I do not want anyone to have access to this key. If the machine is compromised, so is the source (dang but that's life) and perhaps the MySql database too. Since the source is available, so is the key and the attacker can decrypt the data.

What is the best way to avoid storing the key on the server? I assume it would be storing it on a different server but that seems to pass the ball around a little and not solve the actual problem.

Another question could be 'should I even be using an AWS EC2 server' and how secure are one of these things if all patches are applied.

Does anyone have any insight on this sort of situation? I am a pretty good programmer but not the best versed in security.

  • 2
    The best way to avoid storing they key on the server? Don't store it there. Store it in an environment you trust (i.e. in-house) or in hardware you trust (i.e. in a HSM such as offered by AWS) or if you trust your RAM and your distro's RNG (and the authenticity of the server), you can store the key in a location you trust and transmit it via TLS after each launch.
    – SEJPM
    Jan 7, 2016 at 15:29
  • Thanks for the feedback. It does seem like putting it on the HSM is a better solution than anything I can muster up. It's pretty expensive though. Are AWS cloud servers trustworthy in the first place?
    – codin
    Jan 7, 2016 at 21:32
  • You have to decide whether they are trust worthy (after all you have to trust them). But I'd say they are trust worthy if Amazon likely has no interest in the data (why should Amazon bother looking into your data if there are thousands of other instances?) and governments have no (legally supported) interest in the stuff you do (likely the case if you're not doing something illegal) - after all they're selling you trustworthy computations.
    – SEJPM
    Jan 8, 2016 at 20:19
  • @codin AWS can be part of a HIPAA compliant environment to run applications covered under HIPAA guidelines, so apparently they have the policies and procedures in place to be trusted to process private data. (assuming that your own policies and procedures are in place). They have additional security certifications as well.
    – Johnny
    Jan 31, 2016 at 6:34

3 Answers 3


It depends on what you mean by "storing", as well as "server".

I'm going to assume for sake of answering that there are two "servers" in use now, both on the AWS cloud:

MySQL server.

Application server (which currently has the code with your cryptography key in it).

The MySQL server has no reason to have the key, ever.

The Application server I assume has to work with the decrypted data.

  • IF the application server is doing the decrypting itself, it WILL have the key in memory.
    • You CANNOT know whether that memory was ever saved to disk by AWS, unless you inspect the hardware.
  • IF the application server does not need to do the decryption itself, then it is possible to have a service that takes the MySQL data and decrypts it, sending the data back to the Application server by some public/private key encryption you're satisfied with.

As always, if the key is on AWS, any AWS employee with sufficient access chooses to, as well as anyone else with sufficient access (vendors, Dell after the container full of hardware is shipped back once it's suffered too many failures, etc. etc. etc.).

  • AWS does not use off the shelf Dell hardware, and they securely delete data from decommissioned disks: AWS uses the techniques detailed in DoD 5220.22-M (“National Industrial Security Program Operating Manual “) or NIST 800-88 (“Guidelines for Media Sanitization”) to destroy data as part of the decommissioning process
    – Johnny
    Jan 31, 2016 at 6:38

One approach is to store such sensitive keys, passwords, or other credentials in a particular S3 bucket. That bucket should not be publicly accessible/available. Next, you create an IAM role which has S3 read-only access just to that bucket. Last, when launching your EC2 instance, you assign that IAM role to that instance.

With this sort of approach, your EC2 instance does not need your AWS secret/access key for talking to S3; it is automatically allowed by the IAM role. And then code/scripts on your EC2 instance can download the encryption key (or other credentials) from the S3 bucket, start the process, and then remove those credentials from disk (assuming you stored them on disk on your instance); this should hopefully ensure that those credentials are now only in memory on that EC2 instance.

Note that if you try this approach, you may need to set the permissions on the S3 bucket (and its file) to "allow authenticated AWS user", as your EC2 instance will not have your AWS secret/access key, and thus will not be identified as your account to S3.

Hope this helps!

  • This is the same suggestion offered to me via another source. Using an IAM is interesting method to achieve this and honestly could be the route I move towards implementation.
    – codin
    Feb 2, 2016 at 19:41

It depends on how secure you need to be. For PCI, for example, you need to have two keys.

The first is the data encryption key (DEK). The second is the key encryption key (KEK). You use the DEK to encrypt the data. You use the KEK to encrypt the DEK. It is not required but strongly recommended that you store the KEK in the keystore provided by your OS. Then only the logged in user that created it can access it. We created a hidden user that the application is logged in as to retrieve the KEK.

The point is to make it harder by needing to succeed on multiple attack vectors. One to access the login credentials, one to get access to the keystore, one to get at the DEK wherever you have that stored, and then to get access to the actual data. This is opposed to having the keys in the database. In that case, once the database is compromised, everything is.

You can split your KEK and have half in code to add another level of difficulty. I don't personally like to have it available in plain text, so I obfuscate that half so they have to look at the text and the code, another level of difficulty.

Probably for your purposes, you can get away with just one key stored in the keystore for the user that your app is running as.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .