Does knowledge of SHA256(secret) and SHA256(secret + known constant) give any information about the secret than just SHA256(secret)?


migrated from stackoverflow.com Jan 24 at 20:19

This question came from our site for professional and enthusiast programmers.

  • 1
    $\begingroup$ What do you mean by 'is knowledge of'? $\endgroup$ – Andrew Fan Jan 24 at 18:30

In the first case; the attacker has this knowledge

  • $\operatorname{SHA256}$
  • $x = \operatorname{SHA256}(\text{secret})$

While brute-forcing this hash value $x$, there is one problem. One cannot determine whether this is the pre-image or it is a second pre-image. For password cracking, that is not really important since you find a valid password for the target. For your case, assuming the secret has to be determined exactly, there is no way for the attacker.

In the second case; the attacker has

  • $\operatorname{SHA256}$
  • $x = \operatorname{SHA256}(\text{secret})$
  • $\text{the known constant}$
  • $y = \operatorname{SHA256}(\text{secret}\|\text{the known constant})$

This additional knowledge gives the attacker extra information that can be exploited. While brute-forcing to find the secret, this time the attacker has a new mechanism to distinguish the second pre-images from the secret. Given a secret candidate $candidate_s$ check;

$$ y = \operatorname{SHA256}(candidate_s\|\text{the known constant})$$

Apart from the pre-image, the probability of this equality is negligible since we expect that the SHA256 has collision resistance.

As a result, this gives extra information about the secret that can be exploited.


TLDR - Yes, you should avoid using SHA256(secret||constant).

Detailed explanation

Hash functions based on the Merkle–Damgård construction (SHA1, SHA2 MD5) are vulnerable to a length extension attack, while SHA3 is not vulnerable to this attack.

You have m=message, K=secret and applying SHA256 to K||m, as SHA256 tackles blocks iteratively indeed it will hash m’ = m || Padding, where Padding is data filled in the last block by a hash function.

The main idea of this attack is adding new data and padding to the end:

m’ = m || Padding || NewData || NewPadding

Like a consequence, it will allow generating a valid signature without knowing a secret key.

It means next: if an attacker knows SHA256(secret||constant) he can compute SHA256(secret||constant||some_other_data) in easy way. Take a look at the example with HTTP request in Wikipedia article (link above). It's the second case described by @kelalaka

Safe usage of (secret||constant)

  • Double hashing H' = H(K || H(K || m)), where K is a secret data

  • Adding the secret data to the end before hashing H' = H(K || Padding || m || K )

  • Using an additional hash function inside of Merkle–Damgård construction, H' = f(H(m)), it's a theoretical statement, I've checked it, but it should work fine.

  • Concatenation of the secret with each message block: something like HMAC or just use HMAC(data, secret) instead - IMO, it's the easiest way

  • $\begingroup$ it will allow generating a valid signature - That's not a signature, it's an attempt at a MAC. The question does not specify that they are inquiring about this construction in the context of a MAC. They asked if it leaks any information about the secret. Whether or not that's what they should be asking about is a different question, but as-is this answer doesn't appear to address the question that was asked. $\endgroup$ – Ella Rose Feb 7 at 1:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy