比较散列字符串的最佳方法是什么? (PHP)

时间:2011-03-06 14:46:18

标签: php string comparison

我应该使用if(strcmp(md5($string),$hash)==0)还是if(md5($string)==$hash)

5 个答案:

答案 0 :(得分:23)

在比较哈希值时,你应该非常小心,因为你可能会打开时间攻击的窗口。。

虽然听起来非常违反直觉,但你应该对字符串进行全面比较,避免任何优化(即如果字符不同则提前退出)。

以下是有关此问题的一些链接:

以下是一些想法,以解决它:

答案 1 :(得分:15)

如果您比较字符串,请使用strcmp===。人们更喜欢===,因为strcmp可能令人困惑(成功后返回0,wat。)

您必须使用===,而不是====将把两个操作数转换为整数,如果它们可以解释为这样,并且因为MD5哈希不适合整数,它们将被截断一半。因此,只有哈希的前半部分必须相等。请参阅http://phpsadness.com/sad/47

如果要散列密码,请考虑使用缓慢而强大的散列算法,例如PBKDF2,而不是MD5。

答案 2 :(得分:4)

如果你使用的是比PHP 5.6更新的东西(包括),你应该使用timing attack safe string comparison功能。

prevStatus=false
newStatus=false

while true
do    ping -a www.google.com > /dev/null
pingStatus=$?

prevStatus=$newStatus
if [ $pingStatus == 0 ]
then newStatus=true
else newStatus=false
fi

if [ "$newStatus" != "$prevStatus" ]
 then   
 if [ "$newStatus" == "true" ]
 then echo "internet ON"  >> logfile
 else echo "internet OFF" >> logfile
 fi
fi

prevStatus=$newStatus
sleep 60s
done

(如果您使用的是PHP 5.5或更早版本,see here for equivalents。)

答案 3 :(得分:0)

实际上您应该使用password_verify并使用所有其他password_*函数。 它们以PHP> = 5.5.0提供。

作为后备,您可以使用this polyfill。它目前适用于PHP> = 5.3.7。

如果你真的不能/想要使用它,那么仍然有hash_equals(和那些polyfill)作为@MM。已经说过了。

答案 4 :(得分:-4)

我认为if(md5($string) == $hash)更好,因为你只有一个比较而不是2(stcmp& ==)。

md5只生成不需要二进制安全比较的ascii-chars。