MD5报文摘要算法1执行简介本文描述了MD5报文摘要算法,此算法将对输入的任意长度的信息进行计算,产生一个128位长度的“指纹”或“报文摘要”,假定两个不同的文件产生相同的报文摘要或由给定的报文摘要产生原始信息在计算上是行不通的。MD5算法适合用在数据签名应用中,在此应用中,一个大的文件必须在类似RSA算法的公用密钥系统中用私人密钥加密前被“压缩”在一种安全模式下。MD5算法能在32位机器上能以很快的速度运行。另外,MD5算法不需要任何大型的置换列表。此算法编码很简洁。MD5算法是MD4报文摘要算法的扩展。MD5算法稍慢于MD4算法,但是在设计上比MD4算法更加“保守”。设计MD5是因为MD4算法被采用的速度太快,以至于还无法证明它的正确性,因为MD4算法速度非常快,它处在遭受成功秘密攻击的“边缘”。MD5后退了一步,它舍弃了一些速度以求更好的安全性。它集中了不同的评论家提出的建议,并采取了一些附加的优化措施。它被放在公共的地方以求公众的评论意见,它可能当作一个标准被采纳。作为基于OSI的应用,MD5的对象标识符是:md5OBJECTIDENTIFIER::=iso(1)member-body(2)US(840)rsadsi(113549)digestAlgorithm(2)5}在X.509类型AlgorithmIdentifier[3]中,MD5算法参数应该包括NULL类型。2术语和符号本文中一个“字”是32位,一个“字节”是8位。一系列位串可看成是一系列字节的普通形式,其中的连续的8位看成一个字节,高位在前,同理一系列字节串可看成是一系列32位的字,其中每个连续的4个字节当作一个字,地位在前。我们定义x_i代表“x减去I.如果下划线左边的是一个表达式,则用括号括住,如:x_{i+1}。同样我们用^代表求幂,这样x^i则代表x的i次幂。符号“+”代表字的加,Xs代表32位的值X循环左移s位,not(X)代表X的按位补运算,XvY表示X和Y的按位或运算,XxorY代表X和Y的按位异或运算,XY代表X和Y的按位与运算。3MD5算法描述我们假设有一个b位长度的输入信号,希望产生它的报文摘要,此处b是一个非负整数,b也可能是0,不一定必须是8的整数倍,它可能是任意大的长度。我们设想信号的比特流如下所示:m_0m_1...m_{b-1}下面的5步计算信息的报文摘要。(1)补位MD5算法是对输入的数据进行补位,使得如果数据位长度LEN对512求余的结果是448。即数据扩展至K*512+448位。即K*64+56个字节,K为整数。补位操作始终要执行,即使数据长度LEN对512求余的结果已是448。具体补位操作:补一个1,然后补0至满足上述要求。总共最少要补一位,最多补512位。(2)补数据长度用一个64位的数字表示数据的原始长度b,把b用两个32位数表示。那么只取B的低64位。当遇到b大于2^64这种极少遇到的情况时,这时,数据就被填补成长度为512位的倍数。也就是说,此时的数据长度是16个字(32位)的整数倍数。用M[0...N-1]表示此时的数据,其中的N是16的倍数。(3)初始化MD缓冲器用一个四个字的缓冲器(A,B,C,D)来计算报文摘要,A,B,C,D分别是32位的寄存器,初始化使用的是十六进制表示的数字A=0X01234567B=0X89abcdefC=0Xfedcba98D=0X76543210(4)处理位操作函数首先定义4个辅助函数,每个函数的输入是三个32位的字,输出是一个32位的字。X,Y,Z为32位整数。F(X,Y,Z)=XYvnot(X)ZG(X,Y,Z)=XZvYnot(Z)H(X,Y,Z)=XxorYxorZI(X,Y,Z)=Yxor(Xvnot(Z))这一步中使用一个64元素的常数组T[1...64],它由sine函数构成,T[i]表示数组中的第i个元素,它的值等于经过4294967296次abs(sin(i))后的值的整数部分(其中i是弧度)。T[i]为32位整数用16进制表示,数组元素在附录中给出。具体过程如下:/*处理数据原文*/Fori=0toN/16-1do/*每一次,把数据原文存放在16个元素的数组X中.*/Forj=0to15doSetX[j]toM[i*16+j].end/结束对J的循环/*SaveAasAA,BasBB,CasCC,andDasDD.*/AA=ABB=BCC=CDD=D/*第1轮*//*以[abcdksi]表示如下操作a=b+((a+F(b,c,d)+X[k]+T[i])s).*//*Dothefollowing16operations.*/[ABCD071][DABC1122][CDAB2173][BCDA3224][ABCD475][DABC5126][CDAB6177][BCDA7228][ABCD879][DABC91210][CDAB101711][BCDA112212][ABCD12713][DABC131214][CDAB141715][BCDA152216]/*第2轮**//*以[abcdksi]表示如下操作a=b+((a+G(b,c,d)+X[k]+T[i])s).*//*Dothefollowing16operations.*/[ABCD1517][DABC6918][CDAB111419][BCDA02020][ABCD5521][DABC10922][CDAB151423][BCDA42024][ABCD9525][DABC14926][CDAB31427][BCDA82028][ABCD13529][DABC2930][CDAB71431][BCDA122032]/*第3轮*//*以[abcdksi]表示如下操作a=b+((a+H(b,c,d)+X[k]+T[i])s).*//*Dothefollowing16operations.*/[ABCD5433][DABC81134][CDAB111635][BCDA142336][ABCD1437][DABC41138][CDAB71639][BCDA102340][ABCD13441][DABC01142][CDAB31643][BCDA62344][ABCD9445][DABC121146][CDAB151647][BCDA22348]/*第4轮*//*以[abcdksi]表示如下操作a=b+((a+I(b,c,d)+X[k]+T[i])s).*//*Dothefollowing16operations.*/[ABCD0649][DABC71050][CDAB141551][BCDA52152][ABCD12653][DABC31054][CDAB101555][BCDA12156][ABCD8657][DABC151058][CDAB61559][BCDA132160][ABCD4661][DABC111062][CDAB21563][BCDA92164]/*然后进行如下操作*/A=A+AAB=B+BBC=C+CCD=D+DDend/*结束对I的循环*/(5)输出结果报文摘要的产生后的形式为:A,B,C,D。也就是低位字节A开始,高位字节D结束。现在完成了对MD5的描述,在附录中给出了C形式的程序。4摘要MD5算法实现很容易,它提供了任意长度的信息的“指纹”(或称为报文摘要)。据推测要实现两个不同的报文产生相同的摘要需要2^64次的操作,要恢复给定摘要的报文则需要2^128次操作。为寻找缺陷,MD5算法已经过非常细致的检查。最后的结论是还需要相关的更好的算法和更进一步的安全分析。5MD4和MD5的区别以下是MD5和MD4的不同点:1.加上了第四轮循环。2.每一步增加了一个唯一的常数值。第二轮中的函数g从(XYvXZvYZ)变成了(XZvYnot(Z)),以减少g函数的均衡性。6参考文献[1]Rivest,R.,TheMD4MessageDigestAlgorithm,RFC1320,MITandRSADataSecurity,Inc.,April1992.[2]Rivest,R.,TheMD4messagedigestalgorithm,inA.J.MenezesandS.A.Vanstone,editors,AdvancesinCryptology-CRYPTO'90Proceedings,pages303-311,Springer-Verlag,1991.[3]CCITTRecommendationX.509(1988),TheDirectory-AuthenticationFramework.7附录A-参考应用程序本附录包括以下文件:(摘自RSAREF:ACryptographicToolkitforPrivacy-EnhancedMail:)global.h-全局头文件md5.h--MD5头文件md5c.c--MD5源代码(要得到更多的RSAREF信息,请发e-mai到:rsaref@rsa.com.)附录中还包括:mddriver.c-MD2,MD4andMD5的测试驱动程序。驱动程序默认情况下编译MD5,但如果在C的编译命令行将MD5参数设成2或4,则也可以编译MD2和MD4此应用程序是方便使用的,可用在不同的平台上,在特殊的平台上优化它也并不困难,这留给读者作为练习。例如,在“little-endian”平台上,此平台32位字的最低地址字节最无意义的字节,并且没有队列限制,在MD5变换中的解码的命令调用可以被相应的类型替代。A1global.h/*GLOBAL.H-RSAREF类型和常数*//*当且仅当编译器支持函数原型的声明时,PROTOTYPES必须被设置一次如果还没有定义C编译器的标记,下面的代码使PROTOTYPES置为0。*/#ifndefPROTOTYPES#definePROTOTYPES0#endif/*POINTER定义成一个普通的指针类型*/typedefunsignedchar*POINTER;/*UINT2定义成两字节的字*/typedefunsignedshortintUINT2;/*UINT4定一成四字节的字*/typedefunsignedlongintUINT4;/*PROTO_LIST的定义依赖于上面PROTOTYPES的定义,如果使用了PROTOTYPES,那么PROTO_LIST返回此列表,否则返回一个空列表。*/#ifPROTOTYPES#definePROTO_LIST(list)list#else#definePROTO_LIST(list)()#endifA.2md5.h/*MD5.H-MD5C.C头文件*//*本软件允许被复制或运用,但必须在所有提及和参考的地方标注“RSADataSecurity,Inc.MD5Message-DigestAlgorithm”,也允许产生或运用派生软件,但必须在所有提及和参考的地方标明“derivedfromtheRSADataSecurity,Inc.MD5Message-DigestAlgorithm”RSA数据安全公司(RSADataSecurity,Inc.)从来没有出于任何特定目的陈述过关于此软件的可买性和实用性,它提供了“asis”,没有表达或暗示过任何理由。此声明必须在任何此文件和软件的任何拷贝中保留。*//*MD5context.*/typedefstruct{UINT4state[4];/*state(ABCD)*/UINT4count[2];/*位数量,模2^64(低位在前)*/unsignedcharbuffer[64];/*输入缓冲器*/}MD5_CTX;voidMD5InitPROTO_LIST((MD5_CTX*));voidMD5UpdatePROTO_LIST((MD5_CTX*,unsignedchar*,unsignedint));voidMD5FinalPROTO_LIST((unsignedchar[16],MD5