MD5(Rivest设计)
一、概述
MD5(Message Digest Algorithm 5)是一种广泛使用的散列函数,用于提供消息的完整性保护。它可以将长度小于比特的信息输入,输出固定长度的128比特(16字节)散列值。
输入消息以512比特的分组为单位处理。
二、算法框架
L:消息的长度
N:消息扩充后分组个数
:代表一个分组
三、主要步骤
填充消息(Padding)
在MD5算法中,首先需要对输入信息进行填充,使其位长对512求余的结果等于448,并且填充必须进行,即使其位长对512求余的结果等于448。因此,信息的位长(Bits Length)将被扩展至N*512+448,N为一个非负整数,N可以是零。填充的方法如下:
在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。
在这个结果后面附加一个以64位二进制表示的填充前信息长度,如果二进制表示的填充前信息长度超过64位,则取低64位。经过这两步的处理,信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。这样做的原因是为满足后面处理中对信息长度的要求。
初始化 MD5 缓冲区
MD5 使用 四个 32-bit 寄存器作为中间结果和最终结果的缓冲区,初始化值为:
A=0x01234567, B=0x89ABCDEF, C=0xFEDCBA98, D=0x76543210。
在运算过程中涉及大端和小端的转换问题。
A, B, C, D = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476。(小端)
处理 512bit 分组
将填充后的消息分成512位(64字节)的块,对每个块进行以下处理:
将块分成16个32位字
将512位的块分成16个32位的小端序字,记为M[0]到M[15]。
初始化哈希值
将当前哈希值(A,B,C,D)保存到临时变量(a,b,c,d)中。
主循环
MD5有4轮,每轮16次操作,共64次操作。每轮使用不同的非线性函数:
- 第一轮(F函数): F(X,Y,Z) = (X ∧ Y) ∨ (¬X ∧ Z)
- 第二轮(G函数): G(X,Y,Z) = (X ∧ Z) ∨ (Y ∧ ¬Z)
- 第三轮(H函数): H(X,Y,Z) = X ⊕ Y ⊕ Z
- 第四轮(I函数): I(X,Y,Z) = Y ⊕ (X ∨ ¬Z)
每轮操作形式为:<font style="color:#464646;">a = b + ((a + F(b,c,d) + M[k] + T[i]) <<< s)</font>
- <<< 表示循环左移
- T[i]是预先定义的常数表中的一个值。
- s是循环左移的位数
- k是消息字索引
4轮操作之前,先将前一分组的链接变量复制到另外四个备用记录单元AA、BB、CC、DD。
所有这些完成之后,将a、b、c、d分别在原来基础上再加上AA、BB、CC、DD。
即
然后用数据继续运行以上算法。
最终输出 MD5 哈希值
所有分组处理完成后,将最终的 A, B, C, D 连接成 MD5 哈希值。
四、完整代码
1 | #得到十六进制、128比特的散列值 |
五、实例
MD5(“iscbupt”)=”16838a414adaec12d8d86f735fd183b7”