17

crypt()在 PHP 中使用哈希密码,并试图找出在执行密码检查时测试结果哈希是否相等的最安全方法。

我可以看到三个选项:

选项 1 - 双等号

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

4 回答 4

21

在安全性方面,我更喜欢使用===操作员。===确保两个操作数完全相同,而无需尝试容纳一些强制转换以“帮助”比较以达到成功的匹配 - 因为它在开发时可能会有所帮助,这要归功于 PHP 等松散类型的语言。

当然,其中一个操作数是可信任的。来自数据库的散列是可信任的,而用户输入则不是。

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

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

由于 PHP 尝试将“哈希”转换为一个数字(可能使用atoi),它给出 0。虽然它不太可能crypt返回 0,但我更愿意最大化密码不匹配的情况(并接听支持电话)通过使用===, 而不是允许使用==.

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

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

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

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

于 2013-02-05T16:59:03.977 回答
6

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

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

于 2014-11-21T16:59:07.080 回答
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 包含的值为 16

于 2013-09-13T16:26:30.900 回答
-4

我认为==在你的情况下使用就足够了。

==无论类型如何都检查相等,而===检查相等和类型。

1 == "1"= 真

1 === "1"= 假

由于我们不太关心类型,所以我会保持简单并使用==.

于 2013-02-05T15:58:50.447 回答