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.
- Photo taken in app
- File metadata saved to Postgres via my API
- The server gets presigned URL from Amazon for uploading the files
- The URL is given back to the app as a result of the call in step 2.
- 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?
Thanks!