zoukankan      html  css  js  c++  java
  • 初识md5碰撞与crc32碰撞

    现在是晚上23:29。写这篇文章呢,是因为早些时候我胃疼,是因为凉导致的胃疼。凉呢喝了一些热水,喝完热水胃倒是不疼了,但是由于我喝的是茶叶开水,于是就导致失眠了。想来想去这漫漫长夜也没意思,于是就决定写这个了。

    0X01

            这个md5碰撞到底是个什么东西呢,这是王小云发明的一种破解md5摘要算法的的一种方法。这个md5密文,有16位的md5以及32位的md5,然而,32位的md5密文和16位的md5密文它们的区别就是长度不一样,其他没有什么技术上的区别。将同一个字符串加密为16位md5密文和32位md5密文,在32位的md5中减去前8位和后8位,中间的部分就是它的16位md5。例如将字符串admin加密,admin的16位md5是7a57a5a743894a0e,32位md5是21232f297a57a5a743894a0e4a801fc3,去掉32位的前8位和后8位,你看它中间剩下的是不是就是16位md5了。md5密文是由字母和数字组成的,但是md5不区分大小写,也就是由26个字母和10个数字组成的16位的字符串。所以md5密文的总个数一共就是36的16次方个,也就是全宇宙的md5密文总共有1208925819614600000000000个,虽然这是一个很大的数,但是它终究是有限制的,它就只有这么多个,没有办法再+1了,再多一个就重复了,然而明文呢,却是无限制的,不限长度的有标点、大小写字母以及数字组成的字符串有无数个,这是没有办法估量,因为不限长度。然而这无限种明文却都可以用16位的md5表示出来,要用有限数量的东西去表示另一种无限数量的东西,就势必会存在重复,这就是碰撞。由于数量太大,就用数字来代替举例,例如0~9就是md5密文(有限个数),26个字母就是明文(明文数量远大于密文数量),用0表示a,1表示b,2表示c,最多只能表示10个字母。10个数字表示完前10个字母,然而又必须用10个数字表示完26个字母,那么就只能重复了,这是唯一的解决办法了,9表示的字母是i,i后面的字母是j,那这个j就必须要用已经用过的数字来表示了,这样的话从字母j开始,1个数字最少都要表示2个字母了,这就存在碰撞了。j就又要用0来表示。所以简单来说,碰撞算法就是找到另外一个加密以后md5值与原字符串相同的新字符串。碰撞算法会产生多少个结果呢,这是无法估计的,原因也是因为无法限制明文的长度是多少,假如说100位长度的时候就碰撞出md5值与admin相同的字符串,那长度是1000位呢,是100000呢,会碰撞出多少个字符串?这无法计算。如果限制了长度,万一碰撞不出来呢?就要调大长度了。

    0X02

            碰撞破解对安全的实质性影响?碰撞算法是一种能够100%破解掉md5的一种破解算法(就像穷举一样)。就用网页登陆做为例子,假如存在一个账号:root,它的密码是:a,然后网页向数据库查询账号root的密码的md5是多少,然后再对比输入的密码,如果输入的密码的md5与查询到的md5是一样的,那就说明账号和密码输入正确,允许登陆,否则账号密码错误。假如说a的md5是0,然后碰撞出j的md5密文也是0,那输入账号root和密码j会发生什么情况,肯定是允许登陆,因为原密码a的md5是0,而j的md5也是0,输入的密码的md5和数据库中查询到的密码md5是一样的,那就说明密码正确了,然后j并不是原始密码,而是碰撞出的密码。这就是碰撞破解。

    0X03

            理论上最多加密32的16次方+1次,就一定能碰撞出一个字符串的md5值跟某个字符串的md5相同,因为32的16次方就用完了所有的md5密文,因为md5密文的总个数就只有这么多个。再多1个字符串,就一定会出现两个字符串的md5值完全相同的情况了。这32的16次方对于个人电脑来说是不可能的,然而能够使用超级计算机的话,是100%能解md5的,如果你能够搜集到32的16次方个不同的md5密文所对应的明文,那么你就100%能够破解任何一个md5了。

    0X04

    碰撞破解并不是还原,md5是一种不可逆的加密,也就是说它本身就是无法还原的

    0X05

            crc32碰撞。crc32碰撞的概率相当高,这个我之前并不了解,是我在工作中偶然发现的,当时我还以为我发现了新大陆,结果谷歌一搜,早就有人发现了。这就是crc32碰撞。事件的起因是这样的,前段时间我用Python写了一个破解zip压缩包密码的程序,这个程序我已经开源,放在博客上可以任意下载免费使用,地址是www.tech-era.top/file/hackzip.zip。破解的原理是穷举,然后程序写好以后呢就要测试,于是我压缩了一个空白文本文档,我将压缩包的密码设置为56(设置为56是乱按的),密码设置为数字组成的两位数密码,是因为这只有10的2次方个,也就是字典中的密码只有100个,可以很快就穷举完。当穷举到56程序提示找到密码了,说明我写的这个程序是可以正常的工作的吧,然后我使用了另外一个字典,另外一个字典中并没有正确密码,这样做是因为我想要测试当字典中没有正确密码的时候程序会不会按照设计那样正常运行,然后使用这个我以为没有正确密码的字典时,程序仍然说找到了正确密码,当时我并不知道是为什么,明明字典中就没有正确密码,我还以为是有bug,但是我连这个诡异的bug是怎么出现的都不知道,因为不应该出现这个bug,然后我就用解压软件解压缩测试用的压缩包,当用设置的56做解压密码时成功解压缩了,然后我又用程序穷举出的另一个密码:612,还是成功解压缩了,然后我又用另外一个字典对压缩包进行穷举,发现1251也可以作为密码成功解压缩。然后后来又进行了各种各样的测试发现tm也可以作为密码,所以说这个crc32碰撞的概率很高啊,在10000次的范围内就碰撞出了两个密码(612和1251),当然,测试的前提条件是压缩包的内容的一个空白文本文档。但是压缩包是其他内容时,肯定也是存在碰撞的。

  • 相关阅读:
    python中F/f表达式优于format()表达式
    java8新特性-foreach&lambda
    Java实现多线程的四种方式
    Java中的字符串常量池,栈和堆的概念
    java对象只有值传递,为什么?
    面向对象和面向过程程序设计理解及区别
    String对象为什么不可变
    mybatis_plus插件——生成器
    基于grpc的流式方式实现双向通讯(python)
    Django使用DataTables插件总结
  • 原文地址:https://www.cnblogs.com/xishaonian/p/6512225.html
Copyright © 2011-2022 走看看