I'm not sure the title is accurate, please feel free to rename the question if appropriate.
I'm thinking about a service that stores sensitive data on a remote server. For maximum privacy, the data would be encrypted on the client (using AES) and the encryption key not stored in any place, so that should the server be compromised, sensitive data would still be relatively safe.
Now the problem is, I need a second password to access the service, but this second password must be stored somewhere on the server.
This would be what happens when a user registers:
- user picks a username/password (Password A) and an encryption key (Password B).
- hash(Password A) is stored on the server
- Password B isn't stored anywhere.
then:
- user enters Password A => Password A is transmitted to the server
- server checks hash(Password A) against the user db, grants access
- client downloads preferences and encrypted data
- User enters Password B -> encrypted data is decrypted (locally).
This looks good to me, but the drawback is that the user needs two distinct passwords. This is impractical and also carries the risk that users pick the same string for both, strongly reducing the model's effectiveness.
What I would like is to use two independent passwords but only ask the user a single one.
First attempt
The first idea I had is to ask the user a password, then split it in two and use the first part as service credentials (Password A) while the second part would be the encryption key (Password B).
This has the drawback of reducing the strength of the passwords: if the user-provided string is already weak/short, Password A and Password B would be even weaker.
Second attempt
Another option: use the user-provided password as encryption key (Password B) and use a hash (SHA-256) of that password as service credentials.
Registration:
- user picks a single password PASS
- hash(PASS) is transmitted to the server
- server stores hash(hash(PASS)) with username in the user db
Then:
- user enters PASS
- service sends Password A = hash(PASS) to the server
- server checks hash(Password A) against the user db, grants access
- client downloads preferences and encrypted data
- client decrypts encrypted data with Password B = PASS.
This means that
- a hash of the encryption password travels over the network 2) a
- a hash(hash(encryption key)) is now stored on the server, i.e. alongside the encrypted data
Does this significantly reduces the security of the system? I.e. when an attacker gains access to the server, is it easier to decrypt the sensitive data when knowing hash(hash(encryption key))?
Is there another (better) way to get two independent passwords starting from a single string?