Is this client-side password hash scheme secure? I want to build an app that uses client-side encryption for storing encrypted data on the server. A user-specific master key would be used, so to easily share it between devices a encrypted version of it would be stored on the server.

The user's passphrase would be used for both 1) encrypting the master key and 2) authenticating the user. For this reason the server must not know the passphrase.

The passphrase would be used twice for stretching with PBKDF2, HMAC-SHA256 and a good number of iterations:


First, the encryption key used to encrypt the master key would be derived. A random salt would be used here (also stored on the server with the encrypted key).
Second, a hashed version of the passphrase would be derived. The user email would be the salt.


The stretched passphrase (#2) is then sent to the server instead of the plain passphrase. The server would then use bcrypt to further secure that hash and authenticate the user.

Assuming that all communication happens over HTTPS and the user is forced to pick a strong passphrase, I don't think there is anything wrong with this. Am I wrong?
This is far from secure, assuming a passphrase that a human can remember. The main thing you have to note is that an offline brute force attack on the password can be carried out. This is because the server can guess the password and follow the same procedure and see if decryption works. It is possible to buy a machine that computes billions of hashes a second (for a few thousand dollars). Very few passwords will be strong enough to resist such an attack.

If you can't do anything better than encrypting with a password, then at least it's something. But I wouldn't trust such a solution (not for passwords that I can remember). I suggest finding a different way to propagate a secret key for the client, rather than storing it on the server. (I know that this will be less usable, but security costs...)