找回密码
 注册
搜索
热搜: 超星 读书 找书
查看: 549|回复: 0

[【原创】] MD5算法原理【非首发】

[复制链接]
发表于 2010-4-7 15:53:12 | 显示全部楼层 |阅读模式
The MD5 Message-Digest Algorithm(MD5信息摘要算法)
首发地址:http://www.docin.com/p-48189913.html
作者:王增才(HN911)
说明:本文基于rfc1321,可以说是rfc1321的中文翻译,但在翻译的基础上,笔者加入了自己的理解。
摘要
此算法对输入的任意长度的信息进行计算,生成一个128位的fingerprint(指纹)或信息摘要(message digest)。假定两个信息会产生相同的信息摘要在计算上是不可行的,或者说,任意信息都会产生一个预先确定目标的信息摘要。在一个像RSA这样的公钥密码系统(public-key cryptosystem)里,在用私钥(private key)编码之前,一个大文件必须用一种安全的机制来压缩,MD5算法用于数字签名应用中(digital signature applications)。
MD5算法的目的是能够非常快速的在32位机器中运行。另外,MD5算法不需要任何大型的替代表(substitution table)。该算法能非常紧凑的编码。
MD5算法是对MD4信息摘要算法的扩展。MD5比MD4慢一点点,但是在设计上更保守(conservative)。设计MD5是因为它认为,MD4被采用的太快,而没有被现有的严格审查所证明。因为MD4的速度非常快,它处在遭受成功秘密攻击(risking successful cryptanalytic attack)的边缘。MD5后退了一步,它放弃了一些速度以求更好的安全性。它集中了不同的评论家提出的建议,并采取了一些附加的优化措施。它被放在公共的地方以求公众的评论意见,它可能当作一个标准被采纳。
对基于OSI(Open System Interconnection Reference Model,开放式通信系统互联参考模型)的应用,MD5的对象标识是
md5 OBJECT IDENTIFIER ::=
iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}

在X.509类型AlgorithmIdentifier [3]中,MD5算法参数应该包括NULL类型。

术语和概念
本文中,一个字(word)是32位的,一个字节(byte)是8位的。一系列位串可以看成一系列字节的自然形式,其中每一个连续的8位看成一个字节,每个字节高位在前(非常重要)。类似的,一系列字节可以看成一系列32位的字(32-bit word),其中每一个连续的4个字节(byte)看做一个字(word),每个字低位在前(最不重要)。
定义x_i代表“x减i”。如果下标(subscript)是一个表达式,我们用括号将它括起来,如x_{i+1}。我们使用上标^表示求幂,因此x^i表示x的i次方。
我们定义符号“+”表示字(word)的加法。我们定义X<<<s表示32位值循环左移s位。定义not(X)表示X按位补运算,定义X v Y表示X和Y按位或运算,定义 X xor Y表示X和Y的按位异或运算,定义XY表示X和Y的按位与运算。

MD5算法描述
开始,我们假定我们有一个b位(b-bit)的信息作为输入,并且我们希望找到它的信息摘要。这里的b是一个任意的非负整数。b可能是0,它没有必要是8的整数倍,它可能是任意大的。我们设想信息的比特按下面的方式书写:
m_0 m_1 ... m_{b-1}
下面五个步骤计算信息的信息摘要(message digest)。
步骤1 追加补位(padding bit)
信息被填充(padded)(扩展,extended),为的是使它的长度对512求余的结果是448。那就是,信息被扩展,因此它再加64位即可成为512位的整数倍(the message is extended so that it is just 64 bits shy of being a multiple of 512 bits long.)。补位操作始终要执行,即使信息的长度对512求余的结果是448。
补位按如下方式执行:一个单独的“1”位被追加到信息里,然后追加若干个“0”位,使信息的长度对512求余的结果是448。总之,最小补充一位(1bit)并且最多追加512位。
步骤2 追加长度(append length)
b(在填补位追加之前的信息的长度)的64位表示(64-bit representation)被追加到上一步骤的结果中。当遇到b大于2^64这种极少出现的情况时,那么只有b的低位64位被使用(这些位被作为两个32位字追加,并且,按照以前的惯例,首先追加低位字)。
这时候,信息(在追加了位与b之后)有一个长度,该长度是512位的整数倍。等效地,信息有一个长度,该长度是16个(32位)字。我们定义M[0 ... N-1]表示信息的字串,其中的N是16的倍数。
步骤3 初始化MD缓冲器(MD buffer)
用一个四字的缓冲器four-word buffer(A,B,C,D)被用来计算信息摘要。这里的A,B,C,D都是32位的寄存器(register)。这些寄存器用十六进制的值来初始化,低位在前:
word A: 01 23 45 67
word B: 89 ab cd ef
word C: fe dc ba 98
word D: 76 54 32 10

步骤4 在16-Word块中处理信息
我们首先定义四个辅助函数,每一个辅助函数的输入是3个32位的字并且生成一个32位的字的输出。
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))

每一个位位置(bit position)F充当一个条件:如果X,那么Y,否则Z。因为在同一个位位置(bit position)XY和not(X)Z可能永远不会为1,函数F可能被定义用+代替v,注意,有趣的是,如果X,Y和Z的位是独立的与没有偏见的,F(X,Y,Z)中的每一个位将会是独立的与没有偏见的。
函数G,H与I与函数F类似,因为他们充当按位并行(bitwise parallel)来从X,Y和Z的位中生成它们的输出,在这种情况下,如果X,Y和Z的相应的位是独立的与无偏见的,那么G(X,Y,Z),H(X,Y,Z)与I(X,Y,Z)中的每一个位将会是独立的与无偏见的。注意,函数H是它的输入的按位“异或”(xor)或者“奇偶性”(parity)函数。
这一步中,使用一个64个元素的表T[1 ... 64],该表用一个sine函数构成。我们定义T表示表中第i个元素,它的值等于经过4294967296次abs(sin(i))后的整数部分,这里的i是一个弧度(radian)。表中的元素在附录中给出。
具体操作如下:
/* Process each 16-word block. */
For i = 0 to N/16-1 do
/* Copy block i into X. */
For j = 0 to 15 do
Set X[j] to M[i*16+j].
end /* of loop on j */
/* Save A as AA, B as BB, C as CC, and D as DD. */
AA = A
BB = B
CC = C
DD = D
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T) <<< s). */
/* Do the following 16 operations. */
[ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
[ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
[ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
[ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T) <<< s). */
/* Do the following 16 operations. */
[ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
[ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
[ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T) <<< s). */
/* Do the following 16 operations. */
[ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
[ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
[ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T) <<< s). */
/* Do the following 16 operations. */
[ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
[ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
[ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
[ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
A = A + AA
B = B + BB
C = C + CC
D = D + DD
end /* of loop on i */

步骤5 输出
信息摘要生成后输出的形式为A,B,C,D。那就是,我们以低位字节A开始,并且以高位字节D结束。
现在完成了对MD5的描述,附录中给出了C程序的实现。

总结
MD5信息摘要算法实现简单,并且为信息的任意长度提供一个“指纹”(fingerprint)或者信息摘要(message digest)。据推测要实现两个不同的报文产生相同的摘要需要2^64次的操作,要恢复给定摘要的报文则需要2^128次操作。
为寻找缺陷,MD5算法已经过非常细致的检查。最后的结论是还需要相关的更好的算法和更进一步的安全分析。











参考资料
1. Rfc1321
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|网上读书园地

GMT+8, 2024-5-12 18:13 , Processed in 0.331471 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表