strcmp vs. == vs. === in PHP for checking hash equality

前端 未结 4 1552
暗喜
暗喜 2021-02-19 00:46

I\'m using crypt() to hash passwords in PHP, and am trying to work out the safest way of testing equality of the resulting hash when performing password checks.

相关标签:
4条回答
  • 2021-02-19 01:10

    When it comes to security I prefer to use the === operator. === ensures the two operands are exactly the same, without trying to accomodate some casting in order to "help" the comparison to reach a successful match - as it may help while developing thanks to a loose-typed language, like PHP.

    Of course, one of the operand is to be trusted. A hash from the database is trustable, while the user input is not.

    One can always dither for a while, coming to the conclusion there is no risk using == in a specific case. Maybe. But for instance

      "0afd9f7b678fdefca" == 0 is true
      "aafd9f7b678fdefca" == 0 is also true
    

    as PHP tries to convert the "hash" into a number (probably using atoi) which gives 0. While it is unlikely crypt returns 0, I'd prefer to maximize the cases where the passwords don't match (and answer a support call) by using ===, than allowing a rare case that I didn't think about by using ==.

    As for strcmp, the function returns <0 or >0 if different, and 0 if equal. But

      strcmp("3", 0003) returns 0
      strcmp("0003", 0003) returns -3
    

    which are not surprising after all. A literal 0003 is actually an integer, 3 and since strcmp expects a string, the 3 will be converted to "3". But that shows there is some conversion that may happen in this case, since strcmp is a function, while === is part of the language.

    So my preference in that case goes to === (which is faster than == anyway).

    0 讨论(0)
  • 2021-02-19 01:11

    That is incorrect, please look at the definition of the function. According to PHP:

    Returns < 0 if str1 is less than str2;

    > 0 if str1 is greater than str2,

    and 0 if they are equal

    It returns less than 0 if str1 is less than str2. Note the phrase "less than", it does not return just -1, but any negative value. The same happens when str1 is greater than str2, but it returns a positive, non-zero value. It returns a positive value that can be 1, or any number thereafter.

    strcmp()returns a number that is the difference between the two strings starting with the last character that was found to be similar.

    Here is an example:

    $output = strcmp("red", "blue");

    The variable $output with contain a value of 16

    0 讨论(0)
  • 2021-02-19 01:13

    I think that using == would be sufficient in your case.

    == checks for equality regardless of type, whereas === checks for equality as well as type.

    1 == "1" = True

    1 === "1" = False

    Since we're not too concerned with type, I'd keep it simple and go with ==.

    0 讨论(0)
  • 2021-02-19 01:31

    You should be using the hash_equals() function that is built into PHP. There would be no need to make your own function. The hash_equals() will return a boolean value.

    In my opinion it is usually NOT a good idea to use == or === for comparing strings let alone hashed strings.

    0 讨论(0)
提交回复
热议问题