用于检查哈希等式的strcmp vs. == vs. ===在PHP中

时间:2013-02-05 15:52:53

标签: php string security bcrypt crypt

我正在使用crypt()在PHP中使用哈希密码,并且我正在尝试在执行密码检查时找出最安全的方法来测试结果哈希的相等性。

我可以看到三个选项:

选项1 - Double Equals

function checkPassword($hash, $password)
{
    return crypt($password, $hash) == $hash;
}

选项2 - 三等于

function checkPassword($hash, $password)
{
    return crypt($password, $hash) === $hash;
}

选项3 - strcmp()

function checkPassword($hash, $password)
{
    return strcmp(crypt($password, $hash), $hash) === 0;
}

我的直觉告诉我,由于缺乏类型检查,选项1是一个坏主意,选项2或3可能更好。但是,如果存在===strcmp失败的特定情况,我无法解决。哪个是最安全的?

4 个答案:

答案 0 :(得分:20)

说到安全性,我更喜欢使用===运算符。 ===确保两个操作数完全相同,而不是试图容纳一些转换以“帮助”比较以达到成功匹配 - 因为它可能有助于开发时感谢松散类型的语言,如PHP

当然,其中一个操作数是可信的。数据库中的哈希值是可信的,而用户输入则不可信。

总有一段时间可以抖动,得出结论在特定情况下使用==没有风险。也许。但是例如

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

当PHP尝试将“哈希”转换为数字(可能使用 atoi )时,它给出了0.虽然crypt不太可能返回0,但我更愿意将使用===密码不匹配(并回答支持电话)的情况,而不是使用==允许我没有考虑的罕见情况。

对于strcmp,如果不同,函数返回<0>0,如果相等,则返回0。但

  strcmp("3", 0003) returns 0
  strcmp("0003", 0003) returns -3
毕竟这并不奇怪。文字0003实际上是一个整数3,由于 strcmp 需要一个字符串,3将转换为"3"。但是这表明在这种情况下可能会发生一些转换,因为 strcmp 是一个函数,而===是该语言的一部分。

所以我在这种情况下的偏好是===(无论如何都比==快。)

答案 1 :(得分:6)

您应该使用PHP内置的hash_equals()函数。没有必要自己动手。 hash_equals()将返回一个布尔值。

在我看来,使用==或===来比较字符串通常不是一个好主意,更不用说哈希字符串了。

答案 2 :(得分:0)

这是不正确的,请查看函数的定义。 根据PHP:

Returns < 0 if str1 is less than str2;

> 0 if str1 is greater than str2,

and 0 if they are equal

如果str1小于str2,则返回小于0。注意短语“小于”,它不仅返回-1,而是返回任何负值。当str1大于str2时会发生同样的情况,但它返回一个正的非零值。它返回一个正值,可以是1,或者之后的任何数字。

strcmp()返回一个数字,它是两个字符串之间的差异,从最后一个被发现相似的字符开始。

以下是一个例子:

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

变量$ output with包含值16

答案 3 :(得分:-3)

我认为使用==就足够了。

无论类型如何,

==都会检查是否相等,而===会检查是否存在相等性以及类型。

1 == "1" = True

1 === "1" =错误

由于我们并不太关心类型,因此我会保持简单并与==一起使用。