1

Suppose I have a password, say "thisIsThePassword".
Then I have MD5 hashes of that password followed by an increasing numeric suffix:

MD5("thisIsThePassword1") = c5c038617ea97315f137606c4123789e
MD5("thisIsThePassword2") = 0a52caffe2e7904c832a257a406f903f
MD5("thisIsThePassword3") = 06683298a9c3cdf8940518db54c43758
...

The question is: are those hashes related to each other in any way, so that from one hash it is possible to compute another one without having to bruteforce the password? Hashes are supposed to be totally different and random as soon as you change one bit in the input, but I'm afraid there are some gotchas, maybe when comparing the hash of thisIsThePassword1 with the one of thisIsThePassword11 (and subsequent suffixes starting with "1"). Would it be better or make any difference if we used SHA instead, or make sure the input is always the same length? What function or method should I use if I wanted to make sure that you can't easily compute another of those hashes unless you bruteforce the password?

3
  • Is your concern specifically with MD5 or hashes in general? – schroeder Apr 17 at 12:26
  • 1
    A good hash algorithm will implement an "butterfly/avalanche effect", where it is impossible to detect the original string from the hash. In order to chain 2 hashes together and find similarities, you'd need the seed string, and that would require you to reverse the hash. With a strong hash function like SHA256, this is impossible. In order to figure out a similarity between 2 SHA256 hashes, you'd need to figure out their seeds, and therefore reverse the hash, which isn't possible. TLDR: if you want to make sure you can't compute a different hash, then use a good hash function (like SHA256). – Xiddoc Apr 17 at 12:26
  • @schroeder, common hashes in general, MD5 is just an example of a common hash that is considered "worse" than SHA, but who knows, it might be enough in this case. But it's just an example. – reed Apr 17 at 12:28
3

Most common hash algorithms are designed to produce outputs that are indistinguishable from random, and as a result, even related inputs are not supposed to produce related outputs. Therefore, generating multiple hashes with related input isn't intrinsically insecure. You can use KMAC (related to SHA-3) and BLAKE2b as MACs and they can be used securely with related inputs in this way.

However, MD5, SHA-1, and SHA-2 are vulnerable to length-extension attacks. That means that it is possible, given a hash and the original length of the input, to produce more hash values with the same prefix without knowing about the original input. Therefore, you would not want to use this approach with one of those algorithms, because an attacker could possibly compute and compare additional values to see if they match. The SHA-3 algorithms and BLAKE2b don't have this problem.

If your goal is to hash a password, though, you don't want to use a simple hash function using any construction. Passwords typically don't contain a lot of entropy, and so you want to use a good password hash such as scrypt or Argon2i with a large salt and suitable iteration count. You can either create a new salt for each use or generate a single salt and append a fixed-length counter.

If your secret isn't actually a password but instead a randomly generated secret with enough entropy (at least 128 bits), then you're probably better off using something like HMAC with a strong hash function, or HKDF if you want a key derivation function. You can then provide the secret as the key and the counter as the message to hash, and this will both avoid length-extension attacks and also has much nicer provable security properties.

And, of course, you would never want to use MD5 or SHA-1 for any purpose. They are both broken and you'd want to use something like SHA-2 (if you don't need to worry about length-extension attacks), SHA-3, or BLAKE2b.

2
  • "Length extension attack" was the term I was looking for, thanks. I have a couple of question by the way, out of curiosity. Question #1: if I made sure that the suffix always had the same length, for example password001 (with allowed suffixes from 001 to 999), would it still be vulnerable? I guess not. Question #2: if I hashed the whole string twice, so instead of hash(password + suffix) I'd use hash(hash((password + suffix)), would it still be vulnerable? I guess not, because the first hash would always reduce the strings to a fixed length. – reed Apr 18 at 13:38
  • People can conduct length-extension attacks apply regardless of the suffix being fixed-length, but whether you will accept those values is different. Double hashing will prevent the length-extension attacks, but you'd be better off using HMAC instead with your secret as the key and the counter as the value, assuming your secret is not a password. – bk2204 Apr 18 at 14:29

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.