Home >Backend Development >PHP Tutorial >PHP 中的 == 和“隐式转换”

PHP 中的 == 和“隐式转换”

WBOY
WBOYOriginal
2016-06-23 13:34:151724browse

引言

最近,在 Hacker News 上有一篇帖子(https://news.ycombinator.com/item?id=9484757),提到了一种探测网站密码加密方式的方法。

<?phpvar_dump(md5('240610708') == md5('QNKCDZO'));var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));var_dump('0x1234Ab' == '1193131');

结果都是:

bool(true)bool(true)bool(true)

如果在一个网站,使用240610708作为密码,然后用QNKCDZO登陆,结果可以登录的话,说明密码是以MD5方式保存的。类似的,如果用aaroZmOk作为密码,然后用aaK1STfY登陆,结果可以登录的话,说明密码是以sha1方式保存的。第三种当然就是明文存储了。

分析

以第一组数为例:

md5('240610708') 的结果是:0e462097431906509019562988736854md5('QNKCDZO') 的结果是:0e830400451993494058024219903391

由于 PHP 是弱类型语言,在使用 == 号时,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。此规则也适用于 switch 语句。上述例子中的两个字符串恰好以 0e 的科学记数法开头,字符串被隐式转换为浮点数,实际上也就等效于 0×10^0 ,因此比较起来是相等的。

类似
<?phpvar_dump( 0 == "a" );var_dump( "0" == "a" );

第一个返回的是 true,第二个返回的是 false

结论

PHP中的Hash校验,应该使用“===”,而不应该使用“==”。另外如果生产环境版本足够高的话(PHP >= 5.6.0),最好使用 hash_equals() 函数。

hash_equals() 在比较两个字符串,无论它们是否相等,函数的时间消耗是恒定的,可以用来防止时序攻击。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn