MD5 信息-摘要算法
翻译:newlaos[DFCG][CCG]
备忘录说明:
这篇备忘录讲述的是因特网通讯方面的内容,并不是定义一个因特网标准,因此传播此文件,将不受任何限制。
内容列表:
1、总述
2、术语及符号
3、MD5算法描述
4、概要
5、MD4与MD5的不同
参考
附录 A - 执行参考(文件源代码)
MD5安全考虑及常用攻击方式(newlaos收集补充)
作者地址
1、总述
这个篇文章将详细描述 MD5 信息-摘要算法。这种算法可以将任意长度的信息处理成一个128bit(定长)的"指纹"或"信息摘要"。任意两个不同信息不可能处理成同样的信息摘要,同时根据得到的信息摘要也不可能逆推出原始信息。MD5算法主要用于数字签名,出于安全的考虑,任何信息(明文)在用公钥加密系统(例如RSA)加密传送前,都要用MD5算法处理出一个信息摘要。(newlaos:一个需要传输的明文,先用MD5算法得到一个信息摘要,再用RSA的传送方私钥和接收方公钥对明文进行加密。然后传送方将密文、RSA的传送方公钥及信息摘要传输给接收方。接收方用RSA的接收方私钥和传送方公钥将密文还原成明文,再通过MD5算法得出解密后明文的信息摘要,用它来和传送方发过来的信息摘要对比,如果相同,就说明密文在传送过程中没有被人篡改。)
MD5 算法是为32位计算机设计的,它在32位计算机上处理起来非常快,并且MD5算法不需要任何大的替代表,在编程实现方面也十分简洁易行。
MD5 算法是MD4算法的扩展,仅比MD4稍慢一点,但在设计上更为谨慎。MD4虽然快,但是存在一种漏洞,它导致对不同的内容进行加密却可能得到相同的加密后结果,因而促就了MD5的产生。MD5为了获得更好安全性,在运算速度上做了小小的让步。MD5算法作为一个标准,被至于大众领域以吸取各种好的建议,并进行适当的优化和改善。
2、术语及符号
在这篇文章里,"word(字)"为32-bit的数值,"byte(字节)"为8-bit的数值。一个bit数据流通常解释为byte数据流,每8-bit数据被解释为1-byte,且按高位在前的顺序排列。同理,一个byte数据流通常解释为word(字)数据流,每4-byte被解释为1-word,按的是低位在前的顺序排列。
x_i表示"x sub i",如果写在下方的(下标)是一个表达式,我就用括号将它括起来x_{i+1}。同理,我们用 ^ 代表上标(求幂),那么x^i代表的就是x的i次方。
"+"代表是word(字)的加法运算。X <<< s表示一个32-bit的数值X向左循环移动s位。not(X)表示对X按bit(位)求反,X v Y表示X与Y按bit(位)做与运算,X xor Y表示X与Y按bit(位)做异或运算,XY表示X与Y按bit(位)做且运算
3、MD5算法描述
我们假设有一个b-bit类型的数据,我们希望找到它的信息搞要。在这里b是任意一个无符号整数;b可能为0,不一定是8的倍数,也可能它的数值十分的大。我们设想这个bits(位)型的数据按下面的格式书写:
m_0 m_1 ... m_{b-1} (newlaos:还是记得吗,m_0代表的是第1位(bit)的数据,m下标0,类似数组中的第一个单元)
接下来的5步就是计算这个数据的信息搞要。
MD5简介:
MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2、MD3和MD4发展而来。
Message-Digest泛指字节串(Message)的Hash变换,就是把一个任意长度的字节串变换成一定长的大整数。请注意我使用了"字节串"而不是"字符串"这个词,是因为这种变换 只与字节的值有关,与字符集或编码方式无关。
MD5将任意长度的"字节串"变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,(我刚开始还愚蠢的认为MD5是可逆的算法 感谢Stkman大哥的讲解)换句话说 就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。
MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被"篡改"。举个例子,你将一段话写在一个叫readme.txt文件中,并对这个readme.txt产生一个MD5的 值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现。如果再有一个第三方的认证机构,用MD5还可以防止 文件作者的"抵赖",这就是所谓的数字签名应用。
MD5还广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的, 用户Login的时候,系统是把用户输入的密码计算成MD5值, 然后再去和系统中保存的MD5值进行比较,而系统并不"知道"用户的密码是什么。
一些黑客破获这种密码的方法是一种被称为"跑字典"的方法。有两种方法得到字典,一种是日常搜集的用做密码的字符串表,另一种是用排列组合方法生成的,先用MD5程序计 算出这些字典项的MD5值,然后再用目标的MD5值在这个字典中检索。
即使假设密码的最大长度为8,同时密码只能是字母和数字,共26+26+10=62个字符,排列组合出的字典的项数则是P(62,1)+P(62,2)….+P(62,8),那也已经是一个很天文的数字 了,存储这个字典就需要TB级的磁盘组,而且这种方法还有一个前提,就是能获得目标账户的密码MD5值的情况下才可以。
在软件的加密保护中 很多软件采用MD5保护 但是由于MD5算法为不可逆算法 所以所有的软件都是使用MD5算法作为一个加密的中间步骤,比如对用户名做一个MD5变换,结果再进 行一个可逆的加密变换,做注册机时也只要先用MD5变换,然后再用一个逆算法。所以对于破解者来说只要能看出是MD5就很容易了。
MD5代码的特点明显,跟踪时很容易发现,如果软件采用MD5算法,在数据初始化的时候必然用到以下的四个常数
0x67452301;
0xefcdab89;
0x98badcfe;
0x10325476;
若常数不等 则可能是变形的MD5算法 或者根本就不是这个算法。在内存了也就是
01 23 45 67 89 ab cd ef fe dc ......32 10 16个字节
--------------------------------------------
MD5算法:
第一步:增加填充
增加padding使得数据长度(bit为单位)模512为448。如果数据长度正好是模512为448,增加512个填充bit,也就是说填充的个数为1-512。第一个bit为1,其余全部为0。
第二步:补足长度
将数据长度转换为64bit的数值,如果长度超过64bit所能表示的数据长度的范围,值保留最后64bit,增加到前面填充的数据后面,使得最后的数据为512bit的整数倍。也就是 32bit的16倍的整数倍。在RFC1321中,32bit称为一个word。
第三步:初始化变量:
用到4个变量,分别为A、B、C、D,均为32bit长。初始化为:
A: 01 23 45 67
B: 89 ab cd ef
C: fe dc ba 98
D: 76 54 32 10
第四步:数据处理:
首先定义4个辅助函数:
F(X,Y,Z) = XY v not(X) Z
G(X,Y,Z) = XZ v Y not(Z)
H(X,Y,Z) = X xor Y xor Z
I(X,Y,Z) = Y xor (X v not(Z))
其中:XY表示按位与,X v Y表示按位或,not(X)表示按位取反。xor表示按位异或。
函数中的X、Y、Z均为32bit。
定义一个需要用到的数组:T(i),i取值1-64,T(i)等于abs(sin(i))的4294967296倍的整数部分,i为弧度。
假设前三步处理后的数据长度为32*16*Nbit
第五步:输出:
最后得到的ABCD为输出结果,共128bit。A为低位,D为高位。