A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 上海分校-小影 于 2018-10-26 13:58 编辑

PHPMD5加密的安全隐患

传智播客上海校区  崔长春老师

一.MD5加密是否可靠
从理论上来说,两个任意不同的字符串经过MD5加密之后,都会得到两个不同的结果,从这点上来说,MD5在理论上是安全的。但是!两个不同的字符串如果在比较的过程中有问题而导致相等,那么应用MD5函数时就需要格外小心了,以下是笔者在开发过程中遇到的问题,可以作为PHP中使用MD5函数不甚可靠的例证,不过不能冤枉MD5,这其实是弱类型语言的隐式转换造成的,而MD5本身还是安全的。
二.MD5加密不可靠例证
   我们在PHP7.0版本下(在低版本下问题更多,故选高版本做测试),针对不同的字符串进行加密,然后对其加密后的结果进行比较,他们会不会相等呢?且看一例:
    $a='s1091221200a';
$b='s878926199a';
var_dump(md5($a)==md5($b));
打印的结果是true!你没有看错,他就是true!两个不同的字符串加密之后怎么相等了呢?我们来分析一下:
md5($a)的结果是:"0e940624217856561557816327384675"
md5($b)的结果是:"0e545993274517709034328855841020"
这两个字符串显然也是不同的,其实这类字符串有很多很多,但是他们共同点是都以0e开头,问题就来了,0e开头的字符串在PHP中用两个等号比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方都是0!为验证我们的说法,我们看如下代码:
var_dump(‘0e9876’==’0e123456’);结果为true
var_dump('0'=='0e123456');结果为true
var_dump('0w888'=='0e123456');结果为false
var_dump('0w888'=='0m123456');结果为false
后两个是false推翻了是字符串变成0的可能,前面两个true有力地论证了我们的想法。


三.如何解决这些隐患
   以上这类现象如何避免?在PHP中,两个等号的比较可靠性并不严谨,哪怕是两个类型一样的东西!所以必须是三个等号。例如上面两个等号有问题,但是改成三个等号再比较:
$a='s1091221200a';
$b='s878926199a';
var_dump(md5($a)===md5($b));
得到的结果是false!与我们的预期一致。

4 个回复

正序浏览
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马