# Is SHA-256 safe when used in this way?

I am wondering whether an attacker can gain any useful information from having several hashes of an unknown plaintext that differs in relatively few bits. For example, if provided with:

H1 = SHA-256(TXT | 1)
H2 = SHA-256(TXT | 2)
...
HN = SHA-256(TXT | N)


Can an attacker recover TXT more easily?

-
Pointers as to how to better phrase the question are appreciated. –  louism Jan 19 '14 at 21:28
Yes. However, if the search space for the input text is small (e.g., it is short, alphanumeric, and/or contains little entropy), it is entirely possible for an attacker to quickly attempt billions of possible guesses, and compare them to the hash. –  Stephen Touset Jan 19 '14 at 23:10
@StephenTouset Your point is valid, but I think the question here is "assuming TXT cannot be brute-forced, does having multiple hashes of TXT | N help recover it faster". –  Thomas Jan 20 '14 at 1:21
Sorry. My "yes" was to the question in the subject. SHA-256 is safe in this usage. However, the question posed in the text of the post was the opposite (can TXT be recovered); hence the confusion. –  Stephen Touset Jan 20 '14 at 7:35

What you (most probably) describe is called a "preimage attack", where the attacker tries to find a message that has a specific hash value.

Some related attacks against reduced/weakened versions of SHA-256 are known, but (as far as I know) no such attack was successful against the standard SHA-256 algorithm up to today. So generally, it can be to be considered safe... but: as Stephen Touset already noted in his comment, the security of your final implementation may be influenced negatively if the overall entropy of hashed data is small enough to render things like brute-force attacks feasible. You should definitely keep a critical eye on that aspect.

In fact, there are - at least - two things you should watch out for in relation to salts in general:
(btw.: just in case you don't know... "salt" is the crypto-term for your TXT part)

1. The "Salt Reuse" Problem

Depending on your actual implementation, it could be a mistake to use the same salt in each hash.

If - for example - two users use the same salt, they will produce the same hash. This can be pretty ineffective from a security point of view. In such a case, an attacker could use a reverse lookup table attack to run a dictionary attack on every hash at the same time. The attacker would just have to apply the salt to each "message" guess before the attacker hashes it.

Simpler said: if the salt is reused, lookup tables and rainbow tables could be built for that salt and that would make it easier to crack hashes generated by your implementation. That's why - for example - when implementing user-login systems and hashing user passwords, a new random salt must be generated each time a user creates an account or changes their password.

2. The "Salt Length" Problem

If a salt is too short, an attacker can build a lookup table for every possible salt. Let's take your example and assume it were a real-life implementation where your salt is made up out of the three letters TXT. If an attacker would guess you were only using 3 ASCII characters, then the attacker would merely need to check around and about (95x95x95 =) 857375 possible salts. That may seem like a lot at first glimpse, but creating according lookup tables is rather simple and an according attack pretty manageable with today's hardware.

So, to make it infeasible for an attacker to create a lookup table for every possible salt, the salt must be long.

Personally, I assume it to be a good choice to use salts of the same size as the output of the individually used hash. For example: the output of SHA-256 is 256 bits (= 32 bytes), so I would salt it with (at least) 32 random bytes. But this is more of a personal preference. Others might disagree.

Getting back to your question while pointing at what I noted above: it can be safe, if you implement it correctly - but a small mistake in your implementation may result in a big gain for potential attackers.

-
Minor nit: "where the attacker tries to figure out information about the original message from the hash" is not a preimage attack necessarily. A preimage attack is, given some $f(x)$, try to find an $x'$ such that $f(x) = f(x')$. Even if $f(x)$ exposes some information about $x$, it may not necessarily lead to a preimage attack. This is related to the notion of a hard-core predicate. –  Reid Jan 20 '14 at 5:34
@Reid Valid point - edited - thanks. –  e-sushi Jan 20 '14 at 6:47