MD5 信息摘要算法
meta
- 发布时间:1992-04
- 原文链接:The MD5 Message-Digest Algorithm
- 翻译日期:2024-05-15
- 翻译作者:联系或纠错
1. 摘要
本文描述了 MD5 信息摘要算法。该算法将任意长度的信息作为输入,并产生一个 128 位的“指纹”或“信息摘要”作为输出。产生两个具有相同信息摘要的信息,或者产生任何具有给定预先指定的目标信息摘要的信息,被认为是计算上不可行的。MD5 算法旨在用于数字签名应用程序,其中必须在使用诸如 RSA 的公钥密码系统加密之前以安全的方式“压缩”大文件。
MD5 算法的设计在 32 位的机器上运行非常快。此外,MD5 算法不依赖于任何映射表,算法可以编码得非常紧凑。
MD5 算法是 MD4 信息摘要算法的扩展。MD5 稍微比 MD4 慢一点,但是在设计上更“保守”,MD5 被设计的原因是因为人们认为 MD4 的使用速度可能比现有的严格审查所证明的要快;由于 MD4 被设计得特别快,就成功进行密码分析攻击的风险而言,它处于 “边缘”。MD5 后退了一点,放弃了一点速度,最终以获得更大的安全性。它包含了不同审阅者提出的一些建议,并包含其他优化。 MD5 算法正在被置于公共领域以供审查并可能被采用为标准。
对于基于 OSI 的应用程序,MD5 的对象标识符是 md5 OBJECT IDENTIFIER ::= iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5
。在 X.509 类型 AlgorithmIdentifier 中,MD5 的参数应该具有类型 NULL。
2. 符号和专业用语
本文档中,“word”是 32 位的量,“byte”是 8 位的量。位序列可以按照自然方式解释为字节序列,其中每个连续的 8 位组被解释为一个字节,其中每个字节的高位(最高有效位)被列为第一个。类似地,字节序列可以按照自然方式解释为 32 位字序列,其中每个连续的 4 个字节被解释为一个字,其中每个字的低位(最低有效位)被列为第一个。
x_i
表示 x sub i
。如果下标是一个表达式,我们用大括号括起来,如 x_{i+1}
。类似地,我们使用 ^
表示上标(指数),因此 x^i
表示 x 的 i 次幂。
我们用 +
来表示字的加法(即,模 2^32 加法)。让 X <<< s 表示通过将 X 循环左移 s 位获得的 32 位值。让 not(X)
表示 X 的位补码,让 X v Y
表示 X 和 Y 的位或。让 X xor Y
表示 X 和 Y 的位异或,让 XY
表示 X 和 Y 的位与。
3. MD5 算法描述
我们首先假设我们有一个 b 位的信息作为输入,并且我们希望找到它的信息摘要。这里 b 是任意的非负整数;b 可以是零,它不需要是 8 的倍数,它可以是任意大的。我们将信息的位写成如下形式:m_0 m_1 ... m_{b-1}
。接下来执行以下五个步骤来计算信息的信息摘要。
3.1 第一步。追加填充位
将信息“填充”(扩展),使其长度(以位为单位)对 512 取模为 448。也就是说,将信息扩展,使其只比 512 的倍数位长多 64 位。填充总是执行的,即使信息的长度对 512 取模为 448。
填充按照一下方式进行,首先在信息后面追加一个单独的“1”,然后追加“0”,使得填充后的信息的长度对 512 取模为 448。总之,至少追加一个位,最多追加 512 位。
3.2 第二步。追加长度
用 64 个比特位(位的长度)的 b 的 64 位表示(在填充之前)追加到上一步的结果中。如果 b 大于 2^64,则只使用 b 的低 64 位。 (这些位按照前面的约定作为两个 32 位字追加,低位字先追加。)
此时,结果信息(在填充位和 b 之后)的长度是 512 的倍数。等价地,该消息的长度是 16(32 位)word 的倍数。让 M[0 … N-1] 表示结果消息的word,其中 N 是 16 的倍数。
3.3 第三步。初始化 MD 缓冲区
一个四字缓冲区(A、B、C、D)用于计算信息摘要。这里的每个 A、B、C、D 都是一个 32 位的寄存器。这些寄存器的初始化值如下(以十六进制表示,低位字先):
1 | word A: 01 23 45 67 |
3.4 第四步。以 16 个字为单位处理消息
我们首先定义四个辅助函数,每个函数都以三个 32 位字作为输入,并产生一个 32 位字作为输出。
1 | F(X,Y,Z) = XY v not(X) Z |
在每个比特位上,F 的作用类似于条件:如果 X 则 Y 否则 Z。函数 F 可以使用 + 来定义,而不是 v,因为 XY 和 not(X)Z 永远不会在同一比特位上有 1。有趣的是,如果 X、Y 和 Z 的比特位是独立且随机的,则 F(X,Y,Z) 的每个比特位都是独立且随机的。
函数 G、H 和 I 与函数 F 类似,因为它们以“位并行”的方式从 X、Y 和 Z 的位中产生它们的输出,这样,如果 X、Y 和 Z 的相应位是独立且随机的,则 G(X,Y,Z)、H(X,Y,Z) 和 I(X,Y,Z) 的每个比特位都是独立且随机的。注意,函数 H 是其输入的位异或或“奇偶校验”函数。
这个步骤使用一个从正弦函数构造的 64 元素表 T[1 … 64]。让 T[i] 表示表的第 i 个元素,它等于 4294967296 的整数部分乘以 abs(sin(i)),其中 i 是以弧度表示的。表的元素在附录中给出(译者注:原文并未在附录中给出,本文按照原文的示例代码整理出该序列)。
像下面这样做
1 | /* 处理每个512 比特块 */ |
3.5 第五步。输出
产生的消息摘要作为输出是 A、B、C、D。也就是说,我们从 A 的低位字开始,以 D 的高位字结束。
这就完成了 MD5 的描述。C 语言的参考实现在附录中给出(译者注:本文不含 c 语言实现的附录)。
4. 总结
MD5 信息摘要算法的实现是比较简单的,为任意长度的信息提供了一个“指纹”或“信息摘要”。据推测,得出具有相同消息摘要的两条消息的难度约为 2^64 次操作,而得出具有给定消息摘要的任何消息的难度约为 2^128 次操作。MD5 算法已经过仔细检查以找出弱点。 然而,它是一种相对较新的算法,进一步的安全分析当然是合理的,就像任何此类新提案的情况一样。
5. MD4 与 MD5 的不同点
这儿列举了一些 MD4 与 MD5 的不同点:
- 添加了第四轮的计算
- 每一轮都有一个唯一的加法常数
- 第二轮的函数 g 从 (XY v XZ v YZ) 改为 (XZ v Y not(Z)),使得 g 不那么对称
- 每一轮都添加了上一轮的结果,这促进了更快的“雪崩效应”
- 在第二轮和第三轮中访问输入字的顺序已经改变,使得这些模式不那么相似
- 每一轮的移位量已经近似优化,以产生更快的“雪崩效应”。不同轮次的移位是不同的。
参考文献
- [1] Rivest, R., “The MD4 Message Digest Algorithm”, RFC 1320, MIT and RSA Data Security, Inc., April 1992.
- [2] Rivest, R., “The MD4 message digest algorithm”, in A.J. Menezes and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO ‘90 Proceedings, pages 303-311, Springer-Verlag, 1991.
- [3] CCITT Recommendation X.509 (1988), “The Directory - Authentication Framework.”
附录
1. T 的值
1 | T[1 ... 64] = [ |
2. MD5 的 Python 实现
1 | import math |
3. MD5 的 Go 实现
参考官方实现方式 crypto/md5
1 | package main |