I'm implementing a Dropbox-like API, and one of my requirements is to have the files stored encrypted on the server. It is not required that the files are made unreadable by the server, only that they aren't stored clear on disk. I'm using Python with Flask for the API part and PyCrypto for the encryption.
I know absolutely nothing about crypto and don't want to make anything (too) stupid. This is what I have implemented, please tell me how [un]reasonable it sounds:
- When the user PUTs a file, the content is encrypted as it is read from the network using AES-256 MODE_CTR (I wanted to avoid the block size restriction of MODE_ECB and MODE_CBC)
- The encryption key is the user hashed password: this avoids using a single 'server key' for every stored file, and makes the files unreadable if the user happens to change password
- The counter generation uses Crypto.Util.Counter with a random
initial_valueparameter which is specific to each file and stored in database (just like a password salt)
- I'm considering extending the API to allow the user to provide his own encryption key along with the PUT request. He would then have to provide that same key in his GET to retrieve the deciphered content.
Of course, communication with the API is done over HTTPS.