What is the best way to compare hashed strings? (PHP)

22,392

Solution 1

You should be very careful when comparing hashes directly for things like authentification as you could be opening a window to a timing attack.

Although it sounds very counterintuitive, you should to a full comparison of the string, avoiding any optimizations (i.e. exiting early if a character is different).

Here are some links about the problem:

And here are some ideas in order to fix it:

Solution 2

If you compare strings, use strcmp or ===. People prefer === because strcmp can be confusing (it returns 0 on success, wat).

You must use ===, not ==. == will convert both operands to integers if they can be interpreted as such, and because an MD5 hash doesn’t fit in an integer, they will be truncated around the half. Therefore, only the first halves of the hashes have to be equal. See http://phpsadness.com/sad/47.

If you are hashing passwords, consider using a slow and strong hashing algorithm such as PBKDF2, rather than MD5.

Solution 3

If you're using anything newer than PHP 5.6 (and including) you should use timing attack safe string comparison function.

if (hash_equals($expected, $correct)) {

}

(If you're on PHP 5.5 or earlier, see here for equivalents.)

Share:
22,392
webnat0
Author by

webnat0

Updated on July 09, 2022

Comments

  • webnat0
    webnat0 almost 2 years

    Should I use if(strcmp(md5($string),$hash)==0) or if(md5($string)==$hash)

    • Felix Kling
      Felix Kling about 13 years
      Use strcmp in custom sort functions. For "normal" use, comparing the strings directly is easier and easier to read.
    • ereOn
      ereOn over 11 years
      For anyone reading this thread, you probably shouldn't do that at all.
    • caw
      caw almost 10 years
      If you just want to compare hashes reliably, simply use ===. If you really care about security and potential timing attacks (even despite of network jitter), you should take a look at this or this discussion or use the hash_equals() function (PHP 5.6+).
    • rugk
      rugk over 7 years
      No MD5, no MD5, no MD5!
  • BoltClock
    BoltClock over 11 years
    Wow... that's truly sad indeed.
  • Claudiu
    Claudiu over 8 years
    Look @MM answer. Second of all md5 is obsolete (proven that it can be hacked). Use sha (a better, not the best).
  • lszrh
    lszrh over 8 years
    Of course, you should use sha over md5. But the questioner asked which he should use. If someone asks you: "Do you want a strawberry ice cream or a chocolate ice cream?", you cannot answer "I take vanilla ice cream". Furthermore the question is not about using a hash algorithm, but about comparing values.
  • rugk
    rugk over 7 years
    We do not talk about icecream here, but about security. So the answer is indeed "Do not use anything of what you proposed here!". And BTW: Also SHA-1 must not be used for passwords.
  • David
    David almost 7 years
    Who says this is about security? Maybe he just wants to hash contents of a file to see if its equal to another one.
  • Fabiano Araujo
    Fabiano Araujo about 6 years
    I know this is an old answer but it's important to notice that this "sadness" was posted to PHP 5.4.4. 3v4l.org/EDcdY shows us that from versions 5.4.4 to 5.6.30 and 7+, the statement above is not true, though inferior versions will indeed result in a true statement comparing only half of the string.