2023年7月31日发(作者:)

MD5信息摘要算法原理及破解原理虽然⽬前MD5已经宣布可破解了,但是其算法思想还是可以学习的。MD5应⽤1.⼀致性验证

典型应⽤是对⼀段信息(Message)产⽣信息摘要(Message-Digest),以防⽌被篡改。⽐如,在Unix下有很多软件在下载的时候都有⼀个⽂件名相同,⽂件扩展名为.md5的⽂件,在这个⽂件中通常只有⼀⾏⽂本,⼤致结构如:MD5 () = 38b8c2c1093dd0fec383a9d9ac940515作⽤:在我们可以在下载该软件后,对下载回来的⽂件⽤专门的软件(如Windows MD5 Check等)做⼀次MD5校验,以确保我们获得的⽂件与该站点提供的⽂件为同⼀⽂件。2.数字签名MD5的典型应⽤是对⼀段Message(字节串)产⽣fingerprint(指纹),以防⽌被“篡改”。举个例⼦,你将⼀段话写在⼀个叫⽂件中,并对这个产⽣⼀个MD5的值并记录在案,然后你可以传播这个⽂件给别⼈,别⼈如果修改了⽂件中的任何内容,你对这个⽂件重新计算MD5时就会发现(两个MD5值不相同)。如果再有⼀个第三⽅的认证机构,⽤MD5还可以防⽌⽂件作者的“抵赖”,这就是所谓的数字签名应⽤。3.安全访问认证MD5还⼴泛⽤于操作系统的登陆认证上,如在Unix系统中⽤户的密码是以MD5(或其它类似的算法)经Hash运算后存储在⽂件系统中。当⽤户登录的时候,系统把⽤户输⼊的密码进⾏MD5Hash运算,然后再去和保存在⽂件系统中的MD5值进⾏⽐较,进⽽确定输⼊的密码是否正确。

通过这样的步骤,系统在并不知道⽤户密码的明码的情况下就可以确定⽤户登录系统的合法性。这可以避免⽤户的密码被具有系统管理员权限的⽤户知道。MD5将任意长度的“字节串”映射为⼀个128bit的⼤整数,并且是通过该128bit反推原始字符串是困难的,换句话说就是,即使你看到源程序和算法描述,也⽆法将⼀个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有⽆穷多个,这有点象不存在反函数的数学函数。所以,要遇到了md5密码的问题,⽐较好的办法是:你可以⽤这个系统中的md5()函数重新设⼀个密码,如admin,把⽣成的⼀串密码的Hash值覆盖原来的Hash值就⾏了。

(不去⽤MD5反运算明⽂密码,⽽是⽤⼤量的字符串去⽣成MD5密码并⽐对)正是因为这个原因,现在被⿊客使⽤最多的⼀种破译密码的⽅法就是⼀种被称为”跑字典”的⽅法。有两种⽅法得到字典,⼀种是⽇常搜集的⽤做密码的字符串表,另⼀种是⽤排列组合⽅法⽣成的,先⽤MD5程序计算出这些字典项的MD5值,然后再⽤⽬标的MD5值在这个字典中检索。我们假设密码的最⼤长度为8位字节(8 Bytes),同时密码只能是字母和数字,共26+26+10=62个字节,排列组合出的字典的项数则是P(62,1)+P(62,2)….+P(62,8),那也已经是⼀个很天⽂的数字了,存储这个字典就需要TB级的磁盘阵列,⽽且这种⽅法还有⼀个前提,就是能获得⽬标账户的密码MD5值的情况下才可以。这种加密技术被⼴泛的应⽤于Unix系统中,这也是为什么Unix系统⽐⼀般操作系统更为坚固⼀个重要原因。算法原理对MD5算法简要的叙述可以为:MD5以512位分组来处理输⼊的信息,且每⼀分组⼜被划分为16个32位⼦分组,经过了⼀系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将⽣成⼀个128位散列值。1.填充在MD5算法中,⾸先需要对信息进⾏填充,并且填充必须进⾏,即使其位长对512求余的结果等于448(因为后⾯还有个64位表⽰长度,合起来就是512)。

因此,信息的位长(Bits Length)将被扩展⾄N*512+448,N为⼀个⾮负整数,N可以是零。填充的⽅法如下:1. 在信息的后⾯填充⼀个1和⽆数个0,直到满⾜上⾯的条件时才停⽌⽤0对信息的填充。2. 在这个结果后⾯附加⼀个以64位⼆进制表⽰的 填充前信息长度(单位为Bit),如果⼆进制表⽰的填充前信息长度超过64位,则取低64位。经过这两步的处理,信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。这样做的原因是为满⾜后⾯处理中对信息长度的要求。2. 初始化变量初始的128位值为初始链接变量,这些参数⽤于第⼀轮的运算,以⼤端字节序来表⽰,他们分别为:A=0x01234567,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210。(每⼀个变量给出的数值是⾼字节存于内存低地址,低字节存于内存⾼地址,即⼤端字节序。在程序中变量A、B、C、D的值分别为0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476)1. 处理分组数据准备需要⽤到的数据:4个常数: A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;4个函数:F(X,Y,Z)=(X & Y) | ((~X) & Z); G(X,Y,Z)=(X & Z) | (Y & (~Z));

H(X,Y,Z)=X ^ Y ^ Z; I(X,Y,Z)=Y ^ (X | (~Z));把消息分以512位为⼀分组进⾏处理,每⼀个分组进⾏4轮变换,以上⾯所说4个常数为起始变量进⾏计算,重新输出4个变量,以这4个变量再进⾏下⼀分组的运算,如果已经是最后⼀个分组,则这4个变量为最后的结果,即MD5值。每⼀分组的算法流程如下:第⼀分组需要将上⾯四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。从第⼆分组开始的变量为上⼀分组的运算结果,即A = a, B = b, C = c, D = d。主循环有四轮(MD4只有三轮),每轮循环都很相似。第⼀轮进⾏16次操作。每次操作对a、b、c和d中的其中三个作⼀次⾮线性函数运算,然后将所得结果加上第四个变量,⽂本的⼀个⼦分组和⼀个常数。再将所得结果向左环移⼀个不定的数,并加上a、b、c或d中之⼀。最后⽤该结果取代a、b、c或d中之⼀。以下是每次操作中⽤到的四个⾮线性函数(每轮⼀个)。F( X ,Y ,Z ) = ( X & Y ) | ( (~X) & Z )G( X ,Y ,Z ) = ( X & Z ) | ( Y & (~Z) )H( X ,Y ,Z ) =X ^ Y ^ ZI( X ,Y ,Z ) =Y ^ ( X | (~Z) )(&是与(And),|是或(Or),~是⾮(Not),^是异或(Xor))这四个函数的说明:如果X、Y和Z的对应位是独⽴和均匀的,那么结果的每⼀位也应是独⽴和均匀的。F是⼀个逐位运算的函数。即,如果X,那么Y,否则Z。函数H是逐位奇偶操作符。假设Mj表⽰消息的第j个⼦分组(从0到15),常数ti是4294967296*abs( sin(i) )的整数部分,i 取值从1到64,单位是弧度。(4294967296=232)现定义:FF(a ,b ,c ,d ,Mj ,s ,ti ) 操作为 a = b + ( (a + F(b,c,d) + Mj + ti) << s)GG(a ,b ,c ,d ,Mj ,s ,ti ) 操作为 a = b + ( (a + G(b,c,d) + Mj + ti) << s)HH(a ,b ,c ,d ,Mj ,s ,ti) 操作为 a = b + ( (a + H(b,c,d) + Mj + ti) << s)II(a ,b ,c ,d ,Mj ,s ,ti) 操作为 a = b + ( (a + I(b,c,d) + Mj + ti) << s)注意:“<<”表⽰循环左移位,不是左移位。彩虹表如果将哈希后的密⽂⽐作⼀把锁,暴⼒破解的⽅法就是现场制作各种各样不同齿形的钥匙,再来尝试能否开锁,这样耗时⽆疑很长;我以前错误理解的“彩虹表”是事先制作好所有齿形的钥匙,全部拿过来尝试开锁,这样虽然省去了制作钥匙的时间,但是后来发现这些钥匙实在是太多了,没法全部带在⾝上。⽽真正的彩虹表,是将钥匙按照某种规律进⾏分组,每组钥匙中只需要带最有特点的⼀个,当发现某个“特征钥匙” 差⼀点就能开锁了,则当场对该钥匙进⾏简单的打磨,直到能开锁为⽌。这种⽅法是既省⼒⼜省时的.哈希碰撞哈希碰撞就是⼀种优化过算法,其基本原理就是把密码明⽂对应的MD5与你的MD5进⾏对⽐,因为经过⼀些优化,所以⽆论是时间上,还是空间都很很快,感兴趣的可以查⼀下王⼩云教授关于哈希碰撞的论⽂.常⽤破解MD5⽅法⽬前来说,破解MD5加密的最有效的⽅法就是 哈希碰撞+彩虹表+对应秘钥,⼀些⽹络⿊客会在⼀些明⽂存储⽤户密码的⽹站上窃取信息,假如⿊客有⼀亿条数据,因为都是真实⽤户所以经过哈希碰撞之后,你的密码被破译出来的⼏率就真的⾮常⼤了,那破译不出来的可能就是因为⼤⼩写和⼀些特殊符号,这就⽤到了彩虹表,最后就是你的秘钥,⽐如你是之前对⽤户的密码进⾏加盐,还是之后对MD5之后的字符串进⾏的特殊处理,只要对⽅知道你的秘钥,那么你密码被破译出来的⼏率就⾮常⾮常⾼了,所以我们说: ⼀个密码系统的安全性只在于密钥的保密性,⽽不在于算法的保密性.总结

MD5本⾝是不可逆和⽆冲突的,但是⽤⼀些巧妙地⽅法会被破解出来.⼀个密码系统的是没有绝对安全的,密码系统只是增加了被破解的代价.参考链接:

2023年7月31日发(作者:)

MD5信息摘要算法原理及破解原理虽然⽬前MD5已经宣布可破解了,但是其算法思想还是可以学习的。MD5应⽤1.⼀致性验证

典型应⽤是对⼀段信息(Message)产⽣信息摘要(Message-Digest),以防⽌被篡改。⽐如,在Unix下有很多软件在下载的时候都有⼀个⽂件名相同,⽂件扩展名为.md5的⽂件,在这个⽂件中通常只有⼀⾏⽂本,⼤致结构如:MD5 () = 38b8c2c1093dd0fec383a9d9ac940515作⽤:在我们可以在下载该软件后,对下载回来的⽂件⽤专门的软件(如Windows MD5 Check等)做⼀次MD5校验,以确保我们获得的⽂件与该站点提供的⽂件为同⼀⽂件。2.数字签名MD5的典型应⽤是对⼀段Message(字节串)产⽣fingerprint(指纹),以防⽌被“篡改”。举个例⼦,你将⼀段话写在⼀个叫⽂件中,并对这个产⽣⼀个MD5的值并记录在案,然后你可以传播这个⽂件给别⼈,别⼈如果修改了⽂件中的任何内容,你对这个⽂件重新计算MD5时就会发现(两个MD5值不相同)。如果再有⼀个第三⽅的认证机构,⽤MD5还可以防⽌⽂件作者的“抵赖”,这就是所谓的数字签名应⽤。3.安全访问认证MD5还⼴泛⽤于操作系统的登陆认证上,如在Unix系统中⽤户的密码是以MD5(或其它类似的算法)经Hash运算后存储在⽂件系统中。当⽤户登录的时候,系统把⽤户输⼊的密码进⾏MD5Hash运算,然后再去和保存在⽂件系统中的MD5值进⾏⽐较,进⽽确定输⼊的密码是否正确。

通过这样的步骤,系统在并不知道⽤户密码的明码的情况下就可以确定⽤户登录系统的合法性。这可以避免⽤户的密码被具有系统管理员权限的⽤户知道。MD5将任意长度的“字节串”映射为⼀个128bit的⼤整数,并且是通过该128bit反推原始字符串是困难的,换句话说就是,即使你看到源程序和算法描述,也⽆法将⼀个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有⽆穷多个,这有点象不存在反函数的数学函数。所以,要遇到了md5密码的问题,⽐较好的办法是:你可以⽤这个系统中的md5()函数重新设⼀个密码,如admin,把⽣成的⼀串密码的Hash值覆盖原来的Hash值就⾏了。

(不去⽤MD5反运算明⽂密码,⽽是⽤⼤量的字符串去⽣成MD5密码并⽐对)正是因为这个原因,现在被⿊客使⽤最多的⼀种破译密码的⽅法就是⼀种被称为”跑字典”的⽅法。有两种⽅法得到字典,⼀种是⽇常搜集的⽤做密码的字符串表,另⼀种是⽤排列组合⽅法⽣成的,先⽤MD5程序计算出这些字典项的MD5值,然后再⽤⽬标的MD5值在这个字典中检索。我们假设密码的最⼤长度为8位字节(8 Bytes),同时密码只能是字母和数字,共26+26+10=62个字节,排列组合出的字典的项数则是P(62,1)+P(62,2)….+P(62,8),那也已经是⼀个很天⽂的数字了,存储这个字典就需要TB级的磁盘阵列,⽽且这种⽅法还有⼀个前提,就是能获得⽬标账户的密码MD5值的情况下才可以。这种加密技术被⼴泛的应⽤于Unix系统中,这也是为什么Unix系统⽐⼀般操作系统更为坚固⼀个重要原因。算法原理对MD5算法简要的叙述可以为:MD5以512位分组来处理输⼊的信息,且每⼀分组⼜被划分为16个32位⼦分组,经过了⼀系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将⽣成⼀个128位散列值。1.填充在MD5算法中,⾸先需要对信息进⾏填充,并且填充必须进⾏,即使其位长对512求余的结果等于448(因为后⾯还有个64位表⽰长度,合起来就是512)。

因此,信息的位长(Bits Length)将被扩展⾄N*512+448,N为⼀个⾮负整数,N可以是零。填充的⽅法如下:1. 在信息的后⾯填充⼀个1和⽆数个0,直到满⾜上⾯的条件时才停⽌⽤0对信息的填充。2. 在这个结果后⾯附加⼀个以64位⼆进制表⽰的 填充前信息长度(单位为Bit),如果⼆进制表⽰的填充前信息长度超过64位,则取低64位。经过这两步的处理,信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。这样做的原因是为满⾜后⾯处理中对信息长度的要求。2. 初始化变量初始的128位值为初始链接变量,这些参数⽤于第⼀轮的运算,以⼤端字节序来表⽰,他们分别为:A=0x01234567,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210。(每⼀个变量给出的数值是⾼字节存于内存低地址,低字节存于内存⾼地址,即⼤端字节序。在程序中变量A、B、C、D的值分别为0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476)1. 处理分组数据准备需要⽤到的数据:4个常数: A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;4个函数:F(X,Y,Z)=(X & Y) | ((~X) & Z); G(X,Y,Z)=(X & Z) | (Y & (~Z));

H(X,Y,Z)=X ^ Y ^ Z; I(X,Y,Z)=Y ^ (X | (~Z));把消息分以512位为⼀分组进⾏处理,每⼀个分组进⾏4轮变换,以上⾯所说4个常数为起始变量进⾏计算,重新输出4个变量,以这4个变量再进⾏下⼀分组的运算,如果已经是最后⼀个分组,则这4个变量为最后的结果,即MD5值。每⼀分组的算法流程如下:第⼀分组需要将上⾯四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。从第⼆分组开始的变量为上⼀分组的运算结果,即A = a, B = b, C = c, D = d。主循环有四轮(MD4只有三轮),每轮循环都很相似。第⼀轮进⾏16次操作。每次操作对a、b、c和d中的其中三个作⼀次⾮线性函数运算,然后将所得结果加上第四个变量,⽂本的⼀个⼦分组和⼀个常数。再将所得结果向左环移⼀个不定的数,并加上a、b、c或d中之⼀。最后⽤该结果取代a、b、c或d中之⼀。以下是每次操作中⽤到的四个⾮线性函数(每轮⼀个)。F( X ,Y ,Z ) = ( X & Y ) | ( (~X) & Z )G( X ,Y ,Z ) = ( X & Z ) | ( Y & (~Z) )H( X ,Y ,Z ) =X ^ Y ^ ZI( X ,Y ,Z ) =Y ^ ( X | (~Z) )(&是与(And),|是或(Or),~是⾮(Not),^是异或(Xor))这四个函数的说明:如果X、Y和Z的对应位是独⽴和均匀的,那么结果的每⼀位也应是独⽴和均匀的。F是⼀个逐位运算的函数。即,如果X,那么Y,否则Z。函数H是逐位奇偶操作符。假设Mj表⽰消息的第j个⼦分组(从0到15),常数ti是4294967296*abs( sin(i) )的整数部分,i 取值从1到64,单位是弧度。(4294967296=232)现定义:FF(a ,b ,c ,d ,Mj ,s ,ti ) 操作为 a = b + ( (a + F(b,c,d) + Mj + ti) << s)GG(a ,b ,c ,d ,Mj ,s ,ti ) 操作为 a = b + ( (a + G(b,c,d) + Mj + ti) << s)HH(a ,b ,c ,d ,Mj ,s ,ti) 操作为 a = b + ( (a + H(b,c,d) + Mj + ti) << s)II(a ,b ,c ,d ,Mj ,s ,ti) 操作为 a = b + ( (a + I(b,c,d) + Mj + ti) << s)注意:“<<”表⽰循环左移位,不是左移位。彩虹表如果将哈希后的密⽂⽐作⼀把锁,暴⼒破解的⽅法就是现场制作各种各样不同齿形的钥匙,再来尝试能否开锁,这样耗时⽆疑很长;我以前错误理解的“彩虹表”是事先制作好所有齿形的钥匙,全部拿过来尝试开锁,这样虽然省去了制作钥匙的时间,但是后来发现这些钥匙实在是太多了,没法全部带在⾝上。⽽真正的彩虹表,是将钥匙按照某种规律进⾏分组,每组钥匙中只需要带最有特点的⼀个,当发现某个“特征钥匙” 差⼀点就能开锁了,则当场对该钥匙进⾏简单的打磨,直到能开锁为⽌。这种⽅法是既省⼒⼜省时的.哈希碰撞哈希碰撞就是⼀种优化过算法,其基本原理就是把密码明⽂对应的MD5与你的MD5进⾏对⽐,因为经过⼀些优化,所以⽆论是时间上,还是空间都很很快,感兴趣的可以查⼀下王⼩云教授关于哈希碰撞的论⽂.常⽤破解MD5⽅法⽬前来说,破解MD5加密的最有效的⽅法就是 哈希碰撞+彩虹表+对应秘钥,⼀些⽹络⿊客会在⼀些明⽂存储⽤户密码的⽹站上窃取信息,假如⿊客有⼀亿条数据,因为都是真实⽤户所以经过哈希碰撞之后,你的密码被破译出来的⼏率就真的⾮常⼤了,那破译不出来的可能就是因为⼤⼩写和⼀些特殊符号,这就⽤到了彩虹表,最后就是你的秘钥,⽐如你是之前对⽤户的密码进⾏加盐,还是之后对MD5之后的字符串进⾏的特殊处理,只要对⽅知道你的秘钥,那么你密码被破译出来的⼏率就⾮常⾮常⾼了,所以我们说: ⼀个密码系统的安全性只在于密钥的保密性,⽽不在于算法的保密性.总结

MD5本⾝是不可逆和⽆冲突的,但是⽤⼀些巧妙地⽅法会被破解出来.⼀个密码系统的是没有绝对安全的,密码系统只是增加了被破解的代价.参考链接: