Ok so basic overview of the environment I'm envisioning: Webapp w/ db backend storing sensitive data, possibly phi; standard user:pass auth due to unteachable users.
My idea was to encrypt row data in sensitive tables stored in a db using a key that was derived from the user's password (ie the hashed pw using a different algorithm from how the pw is stored in db: eg. store for auth: blowfish(pw), encrypt w/ key=md5(pw) ). That way I could store the encryption key in session (in order to allow authenticated user access to their records w/o reentering pw) without increasing the risk of pw leaking and could destroy w/ session and regenerate on login.
- It seems to me that an attacker couldn't use the data if they stole it while "at rest", ie the application was shut off or in a backup.
Drawbacks I can already see:
- If you forget your password, you lose all your data.
- It becomes impossible to edit db contents manually, everything must be authenticated with the pw used to generate encryption key.
- Doesn't protect data while a session exists.
What I'd really like to know:
- Am I missing some fatal flaw in my scheme?
- Is there a better way to store the encryption key while the session is active?
Ok I think I may have been unclear in my original wording of the question. I meant that I'd store a cryptographically secure hash of the password (likely using blowfish) for the authentication, which means a collision or bruteforce of the password won't be easy (unless someone breaks blowfish, which is always a risk). Simultaneously to authentication (when someone enters their password anyway) I'd hash the password using some other algorithm (probably something like md5 since I don't think it needs to be cryptographically secure at this point) which then would be stored in the session and used to encrypt/decrypt the rows belonging to the user who is authenticated for the duration of the session.
My thoughts wrt to increased attack surface are thus:
- If an attacker compromises the hash of the password used for auth they can simply log into the application normally and extract the data that way.
- If an attacker compromises the encryption of the db data then they have everything at that point and there's no point in getting the password. However if they were able to extract the encryption key and for some reason wanted to log into the application they wouldn't benefit from collision attacks on md5 because that's not the hash used to store/authenticate the password. And a collision against one hash is basically guaranteed not to be a collision against another different hashing algorithm.
Possible remediation of below vuln:
- generate a good pseudo random cryptographic key before any data is stored
- encrypt cryptographic key w/ password (I don't need to transform the password for this version I don't think)
- on login decrypt key and store key in session
- use the key to perform encryption/decryption on rest of the data
why I think this might work is you can't differentiate plaintext from incorrectly decrypted gibberish so the ability to check if your guess was correct is lost, even if you have a list of likely possibilities you can't tell if one worked. Also you get no help brute forcing the encryption key because that's now a proper random value.