zoukankan      html  css  js  c++  java
  • MD5能被破解吗?

    一、起因

    最近在做一个普通的登录界面,然后使用到了加密,然后之前朦朦胧胧的就听到MD5这几个字,所以就使用了MD5加密,网上老是说MD5是无法破解的,所以我是很相信的,但是直到我测试了一下验证码,发现我获取到的加密后的验证码拿到那种破解md5密码的网站上面去,居然一秒就破解了,这让怀疑人生,不是说好破解不了的吗?

    二、开始研究md5

    1.md5为什么不安全?

    因为用md5加密后的东西被轻松破解了,所以我突然好奇这玩意是怎么加密解密的,所以随便搜了一下md5可以破解吗,看到这样一个讨论:

     那个说扯淡的大哥的评论我觉得很有道理,所以我点开了那个所谓加密解密的网站,测试了一下:

      var pass = $.md5('666')
      console.log(pass)

    运行结果是:fae0b27c451c728867a567e8c1bb4e53

    去到那个解密网站上试了一下,发现秒解出答案:

     所以我打开了MD5的官网:MD5官方网站

    一切都明白了,官方文档也说了md5的传统使用方法现在会变得不安全:

     上面那些是官网说的,具体去官网看,我就不再赘述了,具体意思是说了3个MD5不安全的原因:

    (1)现在的电脑计算能力都很强,即使md5加密很牛逼,但是由于强大的现代化计算机,一秒可以穷举数以亿次的密码,所以一般那些所谓的破解都是使用穷举类型破解;

    (2)字典表很大,意思是说由于md5很流行,所以有人建立了一个数据库,里面记录了很多简单的密码组合对应的md5密文,如果你经常使用的密码在里面,就会变得很不安全

    (3)md5产生碰撞的几率可能比其他密码函数的几率会大一点,这个我是感受不了,因为我没有仔细研究过为什么会产生碰撞,以及那种类型的密码组合会产生碰撞。

    产生碰撞:即两个不同的密码使用md5加密后可能密文一样,比如我的密码是:‘’abc‘’,那么假设:‘’你滚‘’加密后的md5密文也与我的密码abc加密后的结果一致,那么就叫碰撞,由于碰撞是很不安全的,比如用户1输入了它的密码,然后一个黑客使用穷举的方式进行匹配用户1加密后的密文,如果产生碰撞,那么黑客无需找到和用户1一样的密码加密后才能匹配,他只需要找到别的字符的加密结果也与用户1输入的密码一致就好了。

    这里记录一下md5使用场景的用法:

     整个对比过程大概如上所示,如果别有用心的不法分子想破解你的密码,那么碰撞可能产生这个问题:

    回过头来,继续看看那个所谓的破解md5的网站:

    再测试几个案例:

    var pass = $.md5('hmy666')
      console.log(pass)

    运行结果:51957fc0888a2d125dc50f8a93efdbfc

     这个会破解得出很正常,因为这个密码很简单,况且据我刚刚搜到的关于md5的破解的博客,发现这个网站早在2006年就有人讨论过这个网站可以破解简单的md5,他网站是这样描述的:

     的确运行了十几年了,后台的几十亿数据应该不假,你只要输入它数据库已有的密码对应的md5密文,它能立刻反馈给你,所以其实他并不是破解,他只是在后台查一下已有的数据字典,如果有这个匹配结果,就立马反馈给你,俗称破解。但是只要你输入复杂一点的,比如加入千变万化的中文字符,那么它就要开始它的穷举之路了,我觉得此时才是开始他的破解之路:

      var pass = $.md5('hmy666,你试一试破解我啊?')
      console.log(pass)

    运行结果:f559d04a65a5f8817fa4cbb60b9ccd48

     只要最多等待5天,就会破解给我,但是我觉得可能破解不出来。我注册了他的网站,看看5天之内他能不能破解我的密文。

    2.md5如何提高安全性

    官网也给出了详细的方案,直接看到官网比我讲的好,这里还是简单做一下自我记录:

     (1)用盐的意思就是给他加一点配料,不要简单加密用户的数据;

    拿发送验证码来说,你可以发给前端的验证码是已经加了盐的,就是比如:你发送的验证码是:7981,那么此时你可以自定义一个字符串,拼接在7981的前面和后面,然后再加密发送给前端,前端再根据约定好的字符串进行拼接,然后再加密,然后两者进行比对,官网给出的方案其实是增加了密码的长度,这样加大了穷举的难度。

    (2)长密码,其实这个方案是和用盐一样的,都是为了加长密码的长度来增大穷举难度。

    注意我这里说的是增加了密码的长度,而不是密文的长度,因为md5的加密后的密文都是32位的16进制。它的转换是将你给的字符串的长度转换为字节长度,然后用这个长度生成32位16进制的数字大小,并且是所有的字符串不管多长多短,都是生成一个32为的16进制的数字,所以md5可以存储的无穷的数据,一个字符串对应唯一的md5值,但是一个md5对应多个字符串的数据,这就是上面所说的冲突。

    关于md5加密的算法介绍可以看看这一篇:

    1.https://blog.csdn.net/workdog/article/details/2039997?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&dist_request_id=1328769.82107.16177808514312293&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control

    还有这个论坛下的回复:https://bbs.csdn.net/topics/320163686

    我抄一下:

    md5存储的容量是无限制的,兄弟。。
    
    另外给你说说MD5的原理吧。MD5是定长加密,也就是说不管你多长的东西,加密出来都是固定的位数。。
    
    MD5是一种摘要算法,所以理论上是不可能从签名取得原文(见下面说明)。认为要从MD5的结果中取得原文才算破解,本身就是对摘要算法的误解。它通常应用于数字签名中,用于标识原文的原始性--即在签名后未作任何的修改。如果可以用不同的原文可以产生相同的签名,这也就意味着签名可能失效,就已经可以证明这种摘要算法的不安全。
    
    
    一个安全的摘要算法在设计时必须满足两个要求:其一是寻找两个输入得到相同的输出值在计算上是不可行的,这就是我们通常所说的抗碰撞的;其二是找一个输入,能得到给定的输出在计算上是不可行的,即不可从结果推导出它的初始状态。
    
    反之,如果某种摘要算法不能同时满足上面两个条件,则它就是不安全的。其实主要还是前一个条件,因为从理论上很容易证明后面一个条件基本上都是可以满足的:
    
    摘要算法对任意长的原文产生定长的签名,按照香农的信息论,当原文的长度超过一定的程度的时候,签名中就无法记录原文中的所有信息,这意味着存在着信息的丢失,所以我说理论上不可能从签名中恢复原文。 
    
    为什么说理论上呢?就是说当这种摘要算法被完全攻破时,也就是说可以从签名恢复出任意原文,注意:是任意原文,因为所有的摘要算法的特点就是存在着一个无穷大的碰撞原文的集合。而真正的原文只是其中一份。对应这个无穷大的集合来说,这就是一个无穷小,便是我曾经说过的: 
    
    可能性为零,不表示不可能。 
    
    解释得具体一点是这样:假设原文含有信息量(I),而签名的长度有限(如MD5的128位),则它的信息量只有(i),因为通常 i < I (除非原文非常短),所以可以这么说:I=i+i'。因为I没有限制,而i有限制,则 i' 也是一个没有限制的量。当进行摘要算法后,i' 信息就丢失了。
    
    反过来,如果现在这种摘要算法被攻破了,可以从 i 反推回去,但因为 i' 信息已经丢失,意味着 i + I' (其中 I' 为任意信息)都可能是 I (碰撞)。但 I' 是一个无穷集合,并且 i' 属于 I'。这说明:理论上可以从 I' 中找到 i' 从而恢复出原文 I ,但是可能性为零(1/∞=0)。
    
    但要做到前面一点就不容易了。因为绝对无碰撞的算法不可能是一个摘要算法,而只能是一个无损压缩算法。它必须包含原文的所有信息,也就意味着它一但被攻破,可以唯一地恢复出原文。并且它的结果肯定是不定长的,因为它需要包含原文的所有信息,当然会根据原文的长度而变。仅这两点就决定了,它不可能是一个好的签名算法。 
    
    最主要的一点是:摘要算法的用途决定了,它只要能找到碰撞就足以让它失效,并不需要找到原文。

    上面所说的,md5是存在碰撞的,绝对无碰撞的算法不是一个摘要算法,而在我给的链接的第一篇博客当中有记载了关于碰撞的实验,据说是24天会产生一次碰撞,不过24天会产生一次碰撞对于完成几分钟内的短信验证戳戳有余了,对于密码的加密,md5也还是一个优秀的算法,因为通常你登录网站的方式是密码加验证码,那么黑客即使都拿到了你的密码和验证码加密的md5密文,想要在几分钟内破解根本就是开玩笑。

    (3)第三种解决方法就是不使用md5,去使用其他的加密。

      var pass = $.md5('hmy666,你试一试破解我啊?')
      console.log(pass)
    穷则独善其身,达则兼济天下……
  • 相关阅读:
    Programming In Lua 第一章
    TCP/IP 第四、五章
    wireshark数据包分析实战 第三、四章
    [MFC.Windows程序设计(第2版) 第一章
    wireshark数据包分析实战 第二章
    C++PrimerPlus第6版 第四章——复合类型
    TCP/IP 第三章
    Linux命令行与脚本编程大全第一章
    Flink的并行度设置
    基于HttpClient的工具类HttpUtil
  • 原文地址:https://www.cnblogs.com/hmy-666/p/14628212.html
Copyright © 2011-2022 走看看