I'm building an app and a server. The server is a node.js API with a Postgres backend.

Images created in the app will be stored at Amazon S3. Metadata about the files will be stored in Postgres.

I have zoomed in at two possible solutions for encryption keys. Both involve Amazons Presigned URLs. These URLs are generated by Amazon as a result of a call from my server.

  1. Photo taken in app
  2. File metadata saved to Postgres via my API
  3. The server gets presigned URL from Amazon for uploading the files
  4. The URL is given back to the app as a result of the call in step 2.
  5. The app uses the URL to post the file to Amazon S3

As for the file encryption I could choose to use Amazon Key Management Service (kms), i.e. Amazon generates and keeps track of individually salted encryption keys for each file. My server would need to use the master key to get the presigned URLs generated.

Or I could choose to generate individual encryption keys for each file at my server and store these keys with the rest of the metadata in Postgres. Amazon would still do the encryption/decryption, but I would pass each individual key in the request for presigned URLs instead of passing the master key.

KMS, pro:

  • No encryption keys stored with the file metadata in Postgres

KMS, con:

  • The master key unlocks every file at S3 (but the master key can be rotated)

Custom generated keys, pro:

  • Easier to implement an extra user key by XOR:ing the keys. If a client won't trust my key handling they could add an extra key which only exists on the device, probably in the iOS key chain.

Custom generated keys. con:

  • If the Postgres database is compromised, the files at S3 might also be compromised.

I'm a programmer, not a security expert. If I need to I will consult an expert, but I thought that the experts on this forum might be able to give some more insight first.

Of course other security measures have been taken. The app only talks to the API via HTTPS and the app is authenticated with the API (using Oath2 and JWT).

I really like the presigned URL concept, as this alows the app to be clueless of any keys needed for S3 upload/download.

Should I use kms or generate keys myself?


  • 2
    What's the question?
    – user
    Commented May 31, 2017 at 14:10
  • Should I use kms or generate keys myself?
    – Michael
    Commented May 31, 2017 at 14:11
  • 2
    What is the reason for data encryption?
    – Fis
    Commented May 31, 2017 at 14:14
  • Most clients want to hear that their files are encrypted. Some files are actually sensitive for real (floor plan blue prints).
    – Michael
    Commented May 31, 2017 at 14:16
  • 1
    This has just one problem. When you will wish to change KEK in KMS you have to re-encrypt all DEK's in the DB. If you just want to keep it simple and cheap just avoid the KMS and store KEK in application config.
    – Fis
    Commented May 31, 2017 at 14:41

2 Answers 2


Just to summary the discussion:

you need to know what kind of attacks you want to protect keys against. As we discussed you correctly mentioned pros and cons of both solutions.

I recommended to mix them up so you will use two keys - KEK (key encryption key) and DEK (data encryption key). You will have just one KEK and as many DEKs as of data stored in the database.

When you will be storing the data to the DB you will generate DEK, encrypt the data with the DEK, encrypt the DEK with KEK and store the encrypted DEK together with the data in the database. For reading, you will get data and encrypted DEK from the DB, you use KEK to decrypt DEK and DEK to decrypt the data.

DEK is supposed to be used only in memory of the application. It should not be never stored unencrypted anywhere else. And you should take care of its secure disposal from the memory immediately once it is not needed (i.e. rewrite byte buffer with zeroes and release it - be careful about strings as those are usually immutable).

The correct way of storing and using the KEK should be storing and using it inside of the HSM (KMS) in order it can't be revealed by somebody, even by server / application administrators.

The dark side of it is probably the AWS KMS price. If you would store it in config it can potentially stolen by attacker and later used decrypt the database dump. But ye, you are probably not securing an army site ;)

It is also necessary to mention that if you will ever need to change the KEK you have to re-encrypt all DEKs stored in the DB.

  • Thank you for the summary and the discussion. I want to clarify that I actually won't need to encrypt/decrypt. I just hand over the decrypted DEK to Amazon and get a temporary url to the file including decryption. This url can be easily used in other places in need of the files, for example a report generator. The URLs have an expire time (15 minutes is default)
    – Michael
    Commented May 31, 2017 at 15:02

Revisited.. posting an answer myself as well.

Short answer: I'll go with KMS.

After reading up some more on KMS it actually seems to fit my needs very well, and it's not expensive at all. We already use S3 for file storage and we will use AWS for our production environment when we are ready, so it's easy to add KMS to the setup. I will also let KMS handle other secrets as well, i.e. no more secret config files.

I was afraid that KMS would make it more complicated, but it's actually really easy to work with.

I was also afraid of the price. I thought it would be priced like an HSM, but it's way cheaper.

I'll leave some links here for others to find, should they be in the same situation as me. Unfortunately I don't have enough reputation to be able to post more than two links, so I'll post some of them without the https:// prefix.



I'll probably handle this from within Node.js:

  • github.com/DavidTanner/nodecredstash

Also easy to use from command line:

  • github.com/fugue/credstash

Enlightening reading if you need beginners info as i do:

  1. blog.threatstack.com/cloud-security-best-practicesfinding-securing-managing-secrets-part-1

  2. blog.threatstack.com/cloud-security-best-practices-finding-securing-managing-secrets-part-2

You must log in to answer this question.

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