黑马程序员技术交流社区

标题: 【上海校区】PHP中MD5加密的安全隐患 [打印本页]

作者: 为热爱挥汗    时间: 2018-10-25 22:05
标题: 【上海校区】PHP中MD5加密的安全隐患
本帖最后由 上海分校-小影 于 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!与我们的预期一致。


作者: 小影姐姐    时间: 2018-10-31 11:49

作者: 不二晨    时间: 2018-10-31 14:16

作者: 梦缠绕的时候    时间: 2018-11-1 14:29

作者: 魔都黑马少年梦    时间: 2018-11-1 16:02





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2