What is the most suitable way to encrypt and decrypt sensitive data on a public cloud server disk without storing the decryption key on the server in plaintext?
In our SaaS web/mobile app, following user login a user may upload PDF files containing sensitive customer data to a public cloud server physically hosted by a 3rd party provider (e.g. Amazon/Rackspace). I would like to protect the data on disk by encrypting it before writing it to disk, and unencrypting it when it's read from disk.
A common solution is to use Symmetric encryption e.g. AES and to store the decryption key on the server's filesystem. I want to avoid storing the plaintext decryption key alongside the data in order to protect access to the data on disk wherever it ends up within the 3rd party's infrastructure - e.g. potentially across multiple physical servers and disks (server disks, unencrypted on daily image backup disk arrays) etc.
Conditions: A user should be able to download PDFs which they previously uploaded. An Admin user should be able to view PDFs uploaded by any user.
I'm considering using a user's login password to protect the decryption key(s).
During each user registration an RSA Public/Private keypair would be generated by and stored on the server's disk. The Private key would be stored AES encrypted with user's password (actually the PBKDF2 derived key based on the user's password).
- Plaintext PDF is uploaded to server (over SSL)
- Server generates a random string (R) for AES encryption.
- RSA encrypt R using the user's Public key. RSA encrypt R using the Admin user's Public key. # Allows admin user to decrypt anything AES encrypt PDF with R and
- Store these three encrypted parts to the filesystem.
- Decrypt user's Private key using their login password (via PBKDF2)
- RSA Decrypt R using user's Private key.
- AES Decrypt PDF using R and return it to the user
In this way if somebody has full access to the full filesystem data they cannot decrypt the PDF files unless they also know a password.
Q: Is this a secure solution? Do you see flaws in this? Are there suitable alternatives which I should consider?