strcmp vs. == vs. === 在 PHP 中用于检查哈希相等性

2022-08-30 23:26:38

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

我可以看到三个选项:

选项 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


答案 1

在安全性方面,我更喜欢使用运算符。 确保两个操作数完全相同,而不试图适应一些转换以“帮助”比较以达到成功的匹配 - 因为它可能会有所帮助,这要归功于松散类型的语言,如PHP。======

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

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

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

因为PHP试图将“哈希”转换为一个数字(可能使用atii),给出0。虽然它不太可能返回0,但我更喜欢通过使用最大化密码不匹配的情况(并应答支持电话),而不是允许我使用没有想到的罕见情况。crypt=====

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

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

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

因此,在这种情况下,我更喜欢(这比无论如何都要快)。=====


答案 2

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

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


推荐