Does having a hash of a password jeopardize the security of plaintext that was encrypted with that password?
As usual in password-based cryptography, we'll consider that the password was chosen from a relatively small set, small enough that password enumeration by an adversary can generate passwords including the one of a target user with fair probability, but large enough that additionally computing the (purposely slow) password hash for each password enumerated is too costly for the attacker.
Three cases must be distinguished.
- If the password hash is directly the key of an encryption algorithm, having that password hash is having the encryption algorithm's key, and the security is compromised.
- If the password (rather than its hash) is directly the key of a fast encryption algorithm, then the security is jeopardized by that, not by the disclosure of the password hash. Problem is, an adversary can enumerate passwords and test each to find the right key, under the standard assumption of availability of a suitable plaintext/ciphertext pair, or just ciphertext if plaintext is redundant.
- If the password is processed thru a purposely slow password-to-key derivation function, either different from the one used for the password hash, or the same parametrized for independent results given the same password, then the encryption system is not compromised by the disclosure of the password hash, under the "large enough" hypothesis in preamble, which implies in practice that the password hash is quite slow, and [passwords are imposed to users, or [users are motivated to not have their password guessed, and neither lazy nor stupid]].
(There could in theory be something intermediary between 1 and 3, where the password hash gives a little usable info about the key; but that's unlikely. The closest is that, in a nightmare scenario, the only difference between the password hash and the key is more iterations for the later, and somewhat re-hashing the password hash gives the cipher's key; but neither PBKDF2, nor anything I have studied, has such weakness).
In conclusion:
- Try hard to not let the password hashes leak: password hashing should be a second line of defense.
- Make the results of the password-to-key derivation function and password-to-password-hash function independent (in the sense that one can't be efficiently found from the other). One way that works for most purposely-slow key-or-password derivation functions is to use a different salt, or different prefixes to the same salt (empty being a valid prefix).
- Especially if you must use password-based encryption, take the password-to-key derivation seriously: use a memory-hard construction such as Argon2 or scrypt, and parametrize generously.
Addition per comment:
Are there techniques to use password based encryption but at the same time, have confidence in 128 bit security ?
The best we have combines
- Sensitizing users to the choice of good passwords, perhaps starting with calling these "passphrase" instead. That simple and unobtrusive thing has gone miles in PGP.
- Using Argon2 or other well-thought memory-hard iterated hash to transform password into key, before using it for standard encryption. Merely using a hash requiring sizable memory makes attack using GPUs, FPGAs and ASICs decimal orders of magnitude less attractive than they are to well-funded attackers targeting users of a plain iterated hash like PBKDF2. Password cracking is commonly assisted by GPUs, sometime by FPGAs. I have no hard evidence for ASICs, but technology and greedy mentality in cryptocurrencies are perfect fit.
See this for an exploratory idea: in addition to the above, with a lot of ifs, a memory-hard all-or-nothing transformation of plaintext to ciphertext could force the adversary to decipher the whole file (or a sizable part of the start) in order to test a password. This could be useful to a degree for files of large but still common size.
Regarding the memory-hard iterated hashes: there are iteration, memory, and parallelism parameters to choose.
- When we double the iterations (e.g. increase the user-perceived delay from 4 to 8 seconds),
- Attackers are hit by a double of energy cost, and of time at constant investment.
- Legitimate users also are hit by a sizable increase in energy cost/battery drain, beyond the delay. Thus that adds next to 1 bit of cryptanalytic resistance, but is a pain.
- When we double the memory (e.g. from 4 to 8 GiB), and that whole memory can be put to use within the delay, and a number of plausible assumptions hold, then
- Attackers using specialized hardware are hit by a double of the time at constant RAM cost, and a RAM cost increase at constant time to a possibly lesser but still sizable degree.
- Legitimate users gain some sizable fraction of a bit of key, quite painlessly until they hit the limits of available memory.
- When we double the number of CPUs used, which is possible to small (but increasing) degree, this has a chance of decreasing the user delay to some degree, and shouldn't harm much more than making the machine less responsive for other tacks, and noisier/hotter. Thus that can allow raising the iteration count, see 1. Also, for small delay, that may allow to increase the amount of memory actually used, see 2.
I wish I could rationally tell how better it is to use Argon2d vs directly using (a very fast hash of) the password in AES-128. But can't. Using hypothesis so wild that I won't state them, I get anywhere from +20 to +50 bits. One thing is sure: that can't stretch anywhere near to true 128-bit-ness most passwords chosen by a large sample of computer users.
Is it time to move on to ECIES ?
It does not solve that issue. Any good public-key encryption scheme solves the problem of confidentiality in key distribution, but not the problem of integrity in key distribution. And go figure how to use public-key to authenticate a human to a machine.