MD5 信息摘要算法 101

203 阅读4分钟

MD5 是一种信息摘要算法 (Message-Digest Algorithm)。它接收一个任意长度的信息 (文件) 作为输入,输出一个固定长度 (128 bits) 的信息摘要作为结果。一个文件的 MD5 值就像它的“数字指纹”,只要内容发生变化,对应的“指纹”也会改变,因此它被广泛应用于数字签名。例如:当你需要传输一个文件给别人时,可以同时提供给对方该文件的 MD5 值,当对方完成下载后,通过计算相应的 MD5 值并进行比对,就可以知道文件是否在传输过程中被篡改过。


MD5 算法整个计算过程主要分为五个步骤

第一步,数据填充 (Append Padding Bits)

整个 MD5 算法是把输入信息分组后依次进行处理,每次处理数据的长度是 512 bits,因此需要把输入信息填充到长度是 512 的整数倍且刚好差 64 bits (即取模 512 后余数 448,原因见第二步)。即使原始信息已经满足该条件,填充也必须执行 (唯一性)。

填充方法:首先在原始信息后面添加一个 bit 的“1”,然后按需要添加对应个数的“0”。

第二步,附加长度 (Append Length)

在上一步完成后的数据上再添加 64 bits 的数据使其长度正好是 512 的倍数。添加的内容是原始信息 (未进行数据填充前) 的长度。如果原始文件的长度超过了 2^64,那么只会取长度后 64 bits 的数据。

第三步,初始化信息摘要缓冲区 (Initialize MD Buffer)

这一步会初始化 A, B, C, D 四个寄存器作为缓冲区,每个寄存器的大小是 32 bits (即 4 字节)。第四步涉及的运算都会在这四个寄存器上进行。它们的初始值(十六进制,低位字节在前)如下:

A: 01 23 45 67
B: 89 ab cd ef
C: fe dc ba 98
D: 76 54 32 10
第四步,处理消息组 (Process Message in 16-Word Blocks)

下图是核心的处理流程,首先说明一下图中字母代表的含义:

figure.jpg

A, B, C, D 就是四个缓冲区中的数据。

F 是四个辅助非线性函数 F,G,H,I 中的一个,它们的功能都比较相似,接收 3 个 32 bits 的数据作为输入,输出一个 32 bits 的数据作为结果。每个函数内部都是按位 (bit) 作并行的计算,即位与位之间是独立的。比如 F 的定义如下:

F(X,Y,Z) = ((X & Y) | ~X) & Z

其结果中每个比特位代表的含义是:

if X then Y else Z

M 表示的是一个数组,每个元素是一个 32 bits 的信息数据,因为每次处理的信息长度是 512 bits,所以这个数组有 16 个元素。

K 是一个常量数组,共 64 个元素,存放的是正弦 (sin) 函数表。

S 可以理解为一个常量,只是每次都会变一个值。

整个计算过程是:把 B, C, D 输入给非线性函数获得结果;然后与 A 求和;加上一个 32 bits 的信息数据;再加上一个正弦值;按位左移 S 个位置;最后再加上 B 后赋值给 B,原来的 B, C, D 依次赋值给 C, D, A。因为 M 有 16 个元素,所以这样的过程会执行 16 次,称为一轮。非线性函数有 4 个,当一轮执行完后,会接着用另一个函数执行下一轮,总共 4 轮。因此针对每批 512 bits 长度的信息,会执行 16x4=64 次这样的核心处理流程(正好对应正弦常量数组的个数)。

第五步,输出 (Output)

当完成所有批次的计算后,从 A, B, C, D 以低位到高位的顺序输出其十六进制的值即成为 MD5 值。例如:

7F 13 8A 09 16 9B 25 0E 9D CB 37 81 40 90 73 78

更详细的内容可阅读 Rivest 的 MD5 原稿:RFC1321-The MD5 Message-Digest Algorithm