Given a root hash
root = H(plaintext)
and two (or more) derived hashes
h1 = H(salt1 + root)
h2 = H(salt2 + root)
would the knowledge of h1 and h2 alone increase the chances of finding the root hash or even the plaintext? I'm using SHA256.
To the best of our knowledge, SHA256 does not leak any additional information from related hashes.
On the other hand, the state of "our knowledge" might not be that comprehensive; this security property of SHA256 cannot be derived from the base security assumptions of a hash function (preimage resistance, second preimage resistance and collision resistance), and as far as I know, no one has studied it. While it may be (and likely is) secure, no one has really studied it, and so there there might be a semiobvious leakage that no one happened to find yet.
Now, there is an obvious variation on this which has been studied: HMAC. HMAC is a Message Authentication Code, that is, it has a security assumption that if you give someone (who doesn't know the key) a large number of MAC outputs based on known texts, they still cannot derive the key, or any information about MAC outputs for texts they haven't seen. That is precisely the security assumption that you are looking for; and so HMAC has been analyzed against the exact problem you're looking for. HMAC uses a hash function (for example, SHA256) as an underlying primitive, and it does have a small additional cost over the underlying hash; if you can do some precomputation, this additional cost is just one more hash compression evaluation.
As for how you would use HMAC; well, HMAC has two inputs, a "key" and a "message". You would make your "root" the key and the "salt" the message, and use the output of the MAC as your derived hash.
Given just h1 and h2, if the salts are of any significant length then it will be impossible to uniquely determine "root" even if the hash function is very weak so long as it performs enough "compression". If both salts are known as well as h1 and h2 then the value of root is impractical to determine as long as the hash function is secure.
Recovery of root or plaintext given the above construction given only the derived values would constitute as serious break of the security of SHA256. However, you may not have considered all the relevant threats and the system as a whole may be vulnerable to a length-extension attack. It's worth using the HMAC construction mentioned in poncho's answer rather than trying to do it yourself.
The answer depends on assumptions on plaintext
.
If an adversary can enumerate the possible plaintext
(e.g. if plaintext
is a password, mediocre passphrase, or a published file) then yes: knowledge of h1
or h2
allows finding what plaintext
is, by verifying beyond reasonable doubt an hypothesis made. For some level of protection against that, use a Password-Based Key Derivation Function such as PBKDF2, or better scrypt.
If plaintext
can't be guessed (e.g has 128 bits of entropy), then no: root
and plaintext
will not leak, from a practical standpoint. More precisely, we are safe, for some strong enough hypothesis on H
, that SHA-256
may meet (and meets in practice as far as we know).. or perhaps not (since we have no proof). A suitable hypothesis on H
is being computationally indistinguishable from a random function (aside from the length-extension property, and being a particular public function).
As pointed in another answer, we'd have the HMAC security argument if we used
h1 = HMAC( Hash=SHA-256, Key=root, Message=salt1 )
h2 = HMAC( Hash=SHA-256, Key=root, Message=salt2 )
Presuming root contains enough entropy to make a brute force search infeasible given only $h1$ and $salt1$, the (presumed) preimage resistance of SHA256 means that finding root would still be infeasible even if the attacker also knows the value $h2$ and $salt2$.
Update: First order preimage resistance is usually defined as, for a random value $h$, it is hard to find a message $m$ such that $h = H(m)$. Given the debate this definition has caused in the comment field of another answer, one might argue that this definition is too imprecise and doesn't fully capture the intuitive notion of preimage resistance. Other definitions are of course possible:
Let $n$ be the output length of the hash function $h$ and let $N$ be the maximum input length. Let $r:\{0,1\}^N\mapsto\{0,1\}^N$ be a random function that maps any valid input to another valid input. This function is unknown to adversary but a parameter of the game. Let $BitSelect:\{0,1\}^N\mapsto\{0,1\}$ be such that $BitSelect(m)$ selects a single bit from $m$ based on the value of $h(m)$. Let $f_r:\{0,1\}^N\mapsto\{0,1\}^n\times\{0,1\}$ be such that $f_r(x) = h(r(x)),BitSelect(r(x))$. Define first order preimage resistance such that $h$ is first order preimage restistant if and only if an adversary has less than $2^{-(n-1)}$ advantage distinguishing $f_r$ from the corresponding random function.
Arguably, this definition captures the intuitive notion that first order preimage resistance is about the inability to derive a hash input you didn't get to choose from a hash output you didn't get to choose. Also, if $h$ is not preimage resistant in the common sense, then $f_r$ as defined above will not be IND-CPA.