I'm trying to write a cloud storage application where everything the user uploads is unreadable by the server, encrypted client-side before being sent.
Currently, the flow looks like this:
- User inputs password
- Password is salted and a 256-bit SHA-3 hash is taken
- A new true-random key is generated
- The password hash is used as a key to encrypt the random key and IV (AES-256-CCM)
- The encrypted copy of the random key is sent to the server for storage
- When the user logs in, they download and decrypt this, again with the password
- The random key/IV pair is used to encrypt user files
How bad is it that I'm using a hash with a fixed salt as an encryption key? Is there a better way to do this? The problem is just that I need each password to generate exactly the same key each time, and I didn't see how to do that without a fixed salt, and indeed, a fixed IV in the encryption action.
Also, if it isn't clear why I'm using this key to encrypt another key, my thought is that the second key is significantly more random (minimum 4500 passes of PBKDF2), plus it provides the potential to change the password without having to re-crypt every single user file.