📄 rfc1321---md5报文摘要算法--中文版.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0051)http://shiyiwan.blogchina.com/shiyiwan/3071370.html -->
<HTML><HEAD><TITLE>RFC1321---MD5报文摘要算法--追风小屋</TITLE>
<META http-equiv=Content-Type content="text/html; charset=GBK">
<META http-equiv=Pragma content=no-cache>
<META http-equiv=Cache-Control content=no-cache>
<META http-equiv=Expires content=0>
<META
content="加密解密程序编写记录RFC1321---MD5报文摘要算法伯克利札记(1):前往伯克利的旅程 博客 博客中国 博客动力 blog blogdriver blogger 中国"
name=description>
<META
content="追风小屋 加密解密程序编写记录RFC1321---MD5报文摘要算法伯克利札记(1):前往伯克利的旅程 博客 博客中国 博客动力 blog blogdriver blogger 中国"
name=keywords><LINK href="RFC1321---MD5报文摘要算法--追风小屋.files/diary.css"
type=text/css rel=stylesheet>
<SCRIPT language=JavaScript
src="RFC1321---MD5报文摘要算法--追风小屋.files/UBB.js"></SCRIPT>
<SCRIPT src="RFC1321---MD5报文摘要算法--追风小屋.files/blog.js"
type=text/javascript></SCRIPT>
<META content="MSHTML 6.00.2800.1106" name=GENERATOR></HEAD>
<BODY>
<DIV id=container>
<DIV id=header>
<H1 class=title><A
href="http://shiyiwan.blogchina.com/shiyiwan/index.html">追风小屋</A></H1></DIV>
<DIV id=category><A title=上一篇
href="http://shiyiwan.blogchina.com/shiyiwan/2870592.html">加密解密程序编写记录</A>- -| <A
href="http://shiyiwan.blogchina.com/shiyiwan/index.html">回首页</A> | <A
href="http://shiyiwan.blogchina.com/shiyiwan/catalog_2005.html">2005年索引</A> | -
-<A title=下一篇
href="http://shiyiwan.blogchina.com/shiyiwan/3081160.html">伯克利札记(1):前往伯克利的旅程</A></DIV>
<DIV class=entity>
<H2 class=diaryTitle>RFC1321---MD5报文摘要算法-
-</H2>
<P>
<P>组织:中国互动出版网(<A
href="http://www.china-pub.com/">http://www.china-pub.com/</A>)<BR>RFC文档中文翻译计划(<A
href="http://www.china-pub.com/compters/emook/aboutemook.htm">http://www.china-pub.com/compters/emook/aboutemook.htm</A>)<BR>E-mail:<A
href="mailto:ouyang@china-pub.com">ouyang@china-pub.com</A><BR>译者:()<BR>译文发布时间:2001-11-7<BR>版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须<BR>保留本文档的翻译及版权信息。</P>
<P> </P>
<P>Network Working
Group
R. Rivest<BR>Request for Comments:
1321 MIT Laboratory
for Computer
Science<BR>
and RSA Data Security,
Inc.<BR>
April 1992</P>
<P>MD5 报文摘要算法<BR>(RFC1321——The MD5 Message-Digest Algorithm)</P>
<P>本文地位<BR>本文并非指定一个Internet标准,而是向互联网提供信息,本文可以任意传播,不受限制。<BR>致谢<BR>Don
Coppersmith, Burt Kaliski, Ralph Merkle,David Chaum, 和Noam
Nisan向本文提供极大的帮<BR>助,在此本人表示忠心的感谢。</P>
<P>目录<BR>1 执行简介 1<BR>2 术语和符号 1<BR>3 MD5算法描述 2<BR>4 摘要 4<BR>5 MD4和MD5的区别 4<BR>6 参考文献 4<BR>7 附录A-参考应用程序 4<BR>8 安全事项 18<BR>9 作者地址 18</P>
<P>1 执行简介<BR>本文描述了MD5报文摘要算法,此算法将对输入的任意长度的信息进行计算,产生一个128位<BR>长度的“指纹”或“报文摘要”,假定两个不同的文件产生相同的报文摘要或由给定的报文摘要产生<BR>原始信息在计算上是行不通的。MD5算法适合用在数据签名应用中,在此应用中,一个大的文件必<BR>须在类似RSA算法的公用密钥系统中用私人密钥加密前被“压缩”在一种安全模式下。<BR>MD5算法能在32位机器上能以很快的速度运行。另外,MD5算法不需要任何大型的置换列表。<BR>此算法编码很简洁。MD5
算法是MD4报文摘要算法的扩展。MD5算法稍慢于MD4算法,但是在设<BR>计上比MD4算法更加“保守”。设计MD5是因为MD4算法被采用的速度太快,以至于还无法证明<BR>它的正确性,因为MD4算法速度非常快,它处在遭受成功秘密攻击的“边缘”。MD5后退了一步,<BR>它舍弃了一些速度以求更好的安全性。它集中了不同的评论家提出的建议,并采取了一些附加的优化<BR>措施。它被放在公共的地方以求公众的评论意见,它可能当作一个标准被采纳。<BR>作为基于OSI的应用,MD5的对象标识符是:<BR>md5
OBJECT IDENTIFIER ::=<BR>iso(1) member-body(2) US(840) rsadsi(113549)
digestAlgorithm(2) 5}<BR> 在X.509类型AlgorithmIdentifier
[3]中,MD5算法参数应该包括NULL类型。<BR>2 术语和符号<BR>本文中一个“字”是32位,一个“字节”是8位。一系列位串可看成是一系列字节的普通形式,<BR>其中的连续的8位看成一个字节,高位在前,同理一系列字节串可看成是一系列32位的字,其中每<BR>个连续的4个字节当作一个字,地位在前。<BR>我们定义x_i代表“x减去I".如果下划线左边的是一个表达式,则用括号括住,如:<BR>x_{i+1}。同样我们用^代表求幂,这样x^i则代表x的i次幂。<BR>符号“+”代表字的加,X
<<< s代表32位的值X循环左移s位,not(X)代表X的按位<BR>补运算,X v Y
表示X和Y的按位或运算,XxorY代表X和Y的按位异或运算,XY代表<BR>X和Y的按位与运算。<BR>3 MD5算法描述<BR>我们假设有一个b位长度的输入信号,希望产生它的报文摘要,此处b是一个非负整数,b也可<BR>能是0,不一定必须是8的整数倍,它可能是任意大的长度。我们设想信号的比特流如下所示:<BR>
m_0 m_1 ... m_{b-1}<BR>下面的5步计算信息的报文摘要。<BR>(1)
补位<BR>MD5算法是对输入的数据进行补位,使得如果数据位长度LEN对512求余的结果是448。即数<BR>据扩展至K*512+448位。即K*64+56个字节,K为整数。补位操作始终要执行,即使数据长度LEN<BR>对512求余的结果已是448。
<BR>具体补位操作:补一个1,然后补0至满足上述要求。总共最少要补一位,最多补512位。<BR>(2)
补数据长度<BR> 用一个64位的数字表示数据的原始长度b,把b用两个32位数表示。那么只取B的低64位。<BR>当遇到b大于2^64这种极少遇到的情况时,这时,数据就被填补成长度为512位的倍数。也就是说,<BR>此时的数据长度是16个字(32位)的整数倍数。用M[0
... N-1]表示此时的数据,其中的N是16<BR>的倍数。<BR>(3)
初始化MD缓冲器<BR> 用一个四个字的缓冲器(A,B,C,D)来计算报文摘要,A,B,C,D分别是32位的寄存器,初<BR>始化使用的是十六进制表示的数字
<BR> A=0X01234567
<BR> B=0X89abcdef
<BR> C=0Xfedcba98
<BR> D=0X76543210 <BR>(4)
处理位操作函数<BR>首先定义4个辅助函数,每个函数的输入是三个32位的字,输出是一个32位的字。<BR>X,Y,Z为32位整数。
<BR> F(X,Y,Z) = XY v
not(X) Z<BR> G(X,Y,Z) = XZ
v Y not(Z)<BR> H(X,Y,Z) =
X xor Y xor Z<BR> I(X,Y,Z) = Y xor (X v
not(Z)) <BR>这一步中 使用一个64元素的常数组T[1 ...
64],它由sine函数构成,T[i]表示数组中的第i个元<BR>素,它的值等于经过4294967296次abs(sin(i))后的值的整数部分(其中i是弧度
)。T[i]为32位<BR>整数用16进制表示,数组元素在附录中给出。<BR>具体过程如下: <BR>/* 处理数据原文 */ <BR>For i
= 0 to N/16-1 do <BR>/*每一次,把数据原文存放在16个元素的数组X中. */ <BR>For j = 0 to 15 do
<BR>Set X[j] to M[i*16+j]. <BR>end /结束对J的循环 <BR>/* Save A as AA, B as BB,
C as CC, and D as DD. */ <BR>AA = A <BR>BB = B <BR>CC = C <BR>DD = D
<BR>/* 第1轮*/ <BR>/* 以 [abcd k s i]表示如下操作 <BR>a = b + ((a + F(b,c,d) + X[k] +
T[i]) <<< s). */ <BR>/* Do the following 16 operations. */ <BR>[ABCD 0
7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4] <BR>[ABCD 4 7 5] [DABC 5 12 6]
[CDAB 6 17 7] [BCDA 7 22 8] <BR>[ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11]
[BCDA 11 22 12] <BR>[ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22
16] <BR>/* 第2轮* */ <BR>/* 以 [abcd k s i]表示如下操作 <BR>a = b + ((a + G(b,c,d)
+ X[k] + T[i]) <<< s). */ <BR>/* Do the following 16 operations. */
<BR>[ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20] <BR>[ABCD 5 5 21]
[DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24] <BR>[ABCD 9 5 25] [DABC 14 9 26]
[CDAB 3 14 27] [BCDA 8 20 28] <BR>[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31]
[BCDA 12 20 32] <BR>/* 第3轮*/ <BR>/* 以 [abcd k s i]表示如下操作 <BR>a = b + ((a +
H(b,c,d) + X[k] + T[i]) <<< s). */ <BR>/* Do the following 16
operations. */ <BR>[ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
<BR>[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40] <BR>[ABCD 13 4
41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44] <BR>[ABCD 9 4 45] [DABC 12 11
46] [CDAB 15 16 47] [BCDA 2 23 48] <BR>/* 第4轮*/ <BR>/* 以 [abcd k s
i]表示如下操作 <BR>a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ <BR>/* Do
the following 16 operations. */ <BR>[ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51]
[BCDA 5 21 52] <BR>[ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
<BR>[ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60] <BR>[ABCD 4 6
61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64] <BR>/* 然后进行如下操作 */ <BR>A
= A + AA <BR>B = B + BB <BR>C = C + CC <BR>D = D + DD <BR>end /*
结束对I的循环*/<BR>(5)
输出结果<BR>报文摘要的产生后的形式为:A,B,C,D。也就是低位字节A开始,高位字节D结束。<BR>现在完成了对MD5的描述,在附录中给出了C形式的程序。<BR>4 摘要<BR>MD5算法实现很容易,它提供了任意长度的信息的“指纹”(或称为报文摘要)。据推测要实现<BR>两个不同的报文产生相同的摘要需要2^64次的操作,要恢复给定摘要的报文则需要2^128次操作。<BR>为寻找缺陷,MD5算法已经过非常细致的检查。最后的结论是还需要相关的更好的算法和更进一步<BR>的安全分析。<BR>5 MD4和MD5的区别<BR>以下是MD5和MD4的不同点:<BR>1. 加上了第四轮循环。<BR>2. 每一步增加了一个唯一的常数值。<BR>第二轮中的函数g从(XY
v XZ v YZ)变成了(XZ v Y not(Z)),以减少g函数的均衡性。<BR>6 参考文献<BR>[1] Rivest, R., "The
MD4 Message Digest Algorithm", RFC 1320, MIT and RSA Data Security, <BR>Inc.,
April 1992.<BR>[2] Rivest, R., "The MD4 message digest algorithm", in A.J.
Menezes and S.A. Vanstone, <BR>editors, Advances in Cryptology - CRYPTO
'90Proceedings, pages 303-311, Springer-Verlag, <BR>1991.<BR>
[3] CCITT Recommendation X.509 (1988), "The Directory - Authentication
<BR>Framework."<BR>7 附录A-参考应用程序<BR>本附录包括以下文件:(摘自RSAREF: A Cryptographic
Toolkit for Privacy-Enhanced Mail:)<BR> global.h -
全局头文件<BR>md5.h -- MD5头文件<BR>md5c.c -- MD5源代码<BR>(要得到更多的RSAREF信息,请发e-mai到: <<A
href="mailto:rsaref@rsa.com">rsaref@rsa.com</A>>.)<BR>附录中还包括:<BR>mddriver.c-MD2,
MD4 and
MD5的测试驱动程序。<BR>驱动程序默认情况下编译MD5,但如果在C的编译命令行将MD5参数设成2或4,则也可以编译<BR>MD2和MD4<BR>此应用程序是方便使用的,可用在不同的平台上,在特殊的平台上优化它也并不困难,这留给读<BR>者作为练习。例如,在“little-endian”平台上,此平台32位字的最低地址字节最无意义的字节,<BR>并且没有队列限制,在MD5变换中的解码的命令调用可以被相应的类型替代。<BR>A1
global.h<BR>/* GLOBAL.H - RSAREF 类型和常数*/<BR>/*
当且仅当编译器支持函数原型的声明时,PROTOTYPES必须被设置一次<BR>如果还没有定义C编译器的标记,下面的代码使PROTOTYPES置为0。*/<BR>#ifndef
PROTOTYPES<BR>#define PROTOTYPES 0<BR>#endif</P>
<P>/* POINTER 定义成一个普通的指针类型 */<BR>typedef unsigned char *POINTER;</P>
<P>/* UINT2 定义成两字节的字 */<BR>typedef unsigned short int UINT2;</P>
<P>/* UINT4定一成四字节的字 */<BR>typedef unsigned long int UINT4;</P>
<P>/*
PROTO_LIST的定义依赖于上面PROTOTYPES的定义,如果使用了PROTOTYPES,那么<BR>PROTO_LIST返回此列表,否则返回一个空列表。*/<BR>#if
PROTOTYPES<BR>#define PROTO_LIST(list) list<BR>#else<BR>#define PROTO_LIST(list)
()<BR>#endif<BR>A.2 md5.h<BR>/*MD5.H -
MD5C.C头文件*/<BR>/*本软件允许被复制或运用,但必须在所有提及和参考的地方标注“RSA Data Security, Inc. MD5
<BR>Message-Digest Algorithm”,也允许产生或运用派生软件,但必须在所有提及和参考的地方标明<BR>“derived from the
RSA Data Security, Inc. MD5 Message-Digest Algorithm”<BR>
RSA数据安全公司(RSA Data Security, Inc.)从来没有出于任何特定目的陈述过关于此<BR>软件的可买性和实用性,它提供了“as
is”,没有表达或暗示过任何理由。<BR> 此声明必须在任何此文件和软件的任何拷贝中保留。*/</P>
<P>/* MD5 context. */<BR>typedef struct <BR>{<BR> UINT4
state[4];
/* state (ABCD) */<BR> UINT4
count[2]; /* 位数量, 模 2^64 (低位在前)
*/<BR> unsigned char
buffer[64];
/* 输入缓冲器 */<BR>} MD5_CTX;</P>
<P>void MD5Init PROTO_LIST ((MD5_CTX *));<BR>void MD5Update PROTO_LIST<BR>
((MD5_CTX *, unsigned char *, unsigned int));<BR>void MD5Final PROTO_LIST
((unsigned char [16], MD5_CTX *));<BR>A.3 md5c.c</P>
<P>/* MD5C.C – RSA数据安全公司,MD5报文摘要算法*/<BR>/*本软件允许被复制或运用,但必须在所有提及和参考的地方标注“RSA Data
Security, Inc. MD5 <BR>Message-Digest
Algorithm”也允许产生或运用派生软件,但必须在所有提及和参考的地方标明<BR>“derived from the RSA Data
RSA数据安全公司(RSA Data Security, Inc.)从来没有出于任何<BR>特定目的陈述过关于此软件的可买性和实用性,它提供了“as
is”,没有表达或暗示过任何理由。<BR> 此声明必须在任何此文件和软件的任何拷贝中保留。*/</P>
<P>#include "global.h"<BR>#include "md5.h"</P>
<P>/* Constants for MD5Transform routine.<BR> */</P>
<P>#define S11 7<BR>#define S12 12<BR>#define S13 17<BR>#define S14
22<BR>#define S21 5<BR>#define S22 9<BR>#define S23 14<BR>#define S24
20<BR>#define S31 4<BR>#define S32 11<BR>#define S33 16<BR>#define S34
23<BR>#define S41 6<BR>#define S42 10<BR>#define S43 15<BR>#define S44 21</P>
<P>static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char
[64]));<BR>static void Encode PROTO_LIST<BR> ((unsigned char *, UINT4 *,
unsigned int));<BR>static void Decode PROTO_LIST<BR> ((UINT4 *, unsigned
char *, unsigned int));<BR>static void MD5_memcpy PROTO_LIST ((POINTER, POINTER,
unsigned int));<BR>static void MD5_memset PROTO_LIST ((POINTER, int, unsigned
int));</P>
<P>static unsigned char PADDING[64] = {<BR> 0x80, 0, 0, 0, 0, 0, 0, 0, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -