MD5信息摘要算法描述

前言

  关于MD5算法的详细描述,可参考链接https://www.ietf.org/rfc/rfc1321.txt(英文文档),如链接失效,可访问本人所做的备份https://blog.csdn.net/weixin_44567318/article/details/113060080

术语和约定

  在本文档中,字是32位(32-bit)的,字节是8位(8-bit)的。

   比特(bit)序列可以以一种自然的方式解释为字节(byte)序列,其中每连续的8位比特被解释为一个字节,每个字节的高阶位列在前面(最高有效位在前,MSB)。
在这里插入图片描述
   类似地,字节序列可以被解释为32位字(word)序列,其中每连续的4个字节都被解释为一个字,每个字的低阶字节在前(最低有效字节在前,即小端模式)。
在这里插入图片描述
  用 x_i 表示“ x 下标 i ”。如果下标是一个表达式,则用大括号将其括起来,如 x_{i+1} 所示。
  类似地,我们用∧表示乘方,所以 x^i 表示 x 的 i 次方。
  用符号“+”表示字(word)的相加(即模2^32加法,不考虑进位溢出)。
  用 X <<< s 表示将 X 循环左移 s 位得到的32位值。
  用 not(X) 表示 X 的按位取反。
  用 X v Y 表示 X 和 Y 的按位或。
  用 X xor Y 表示 X 和 Y 的按位异或。
  用 XY 表示 X 和 Y 的按位与。

MD5算法描述

  假设我们有b比特 (bit) 的信息作为输入,这里b是任意的非负整数(即b∈N),b可以是0,它不需要是8的倍数,它可以是任意大的(实际上当消息长度超过2^64比特时,长度(64位)将会发生溢出,数据将被截断处理)。我们假设消息的比特写作如下:

m_0 m_1 ... m_{b-1}

在这里插入图片描述
  执行以下五个步骤来计算消息的摘要。
  

步骤1——添加填充比特

  对消息进行“填充”(扩展),以使它的长度(以比特为单位)对512取模(求余)后等于448。也就是说,对消息进行扩展,以使它的长度(扩展后)距离512位的倍数只差64位(剩下64位用于指明未填充前原数据的长度)。

  `填充总是执行的,即使消息的长度对512取模已经是等于448。

  填充的过程如下:在消息后面追加一个“1”,然后再加上若干个“0”,以使它的长度(以比特为单位)对512取模(求余)后等于448。总之,至少填充1位,最多512位。

在这里插入图片描述

步骤2——附加长度

  b的64位表示(填充比特前的原消息长度)被追加到上一步骤的结果中,在不太可能的情况下b大于264,那么只有b的低64位被使用(这些位以两个32位字和低字在前的方式被追加)。

  此时产生的结果消息(在填充比特和附加64位长度之后)的长度是512位的整数倍。也即是说,此消息的长度是16字的整数倍。让M[0…N-1]表示结果消息的字(word),其中N是结果消息的总字(32位)数, N是16的倍数。
在这里插入图片描述

  

步骤3——初始化MD缓冲

  一个四字(word )缓冲区(A、B、C、D)用于计算消息摘要,这里A,B,C,D每个都是32位寄存器。这些寄存器初始化为以下十六进制值(低字节在前):

word A: 01 23 45 67
word B: 89 ab cd ef
word C: fe dc ba 98
word D: 76 54 32 10

在这里插入图片描述
  以A为例,如果采用小端存储模式(低字节存储在低地址),则0x01存储在地址处,0x67存储在高地址处。

步骤4——以16字的数据块为单位处理消息

  我们首先定义四个辅助函数,每个函数的输入为三个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))

  在每个位中,F 表现为一个条件语句:如果X,那么Y,否则Z。函数 F 可以用 + 而不是 v 来定义,因为 XY 和 not(X)Z 不会在相同的位置上有1。

  函数G,H,I和函数F很相似,它们以“逐位并行”的方式,从X,Y,Z 产生它们的输出。注意函数 H 是其输入的按位的“异或”或“奇偶”函数。

  这一步使用了一个由sin函数构成的64元素的表T[1…64]。用 T[i] 表示表的第 i 个元素,其值为 4294967296 * abs(sin(i))整数部分,其中 i 的单位为弧度

  将步骤2中得到的 N 字(32位)的结果消息,每16字(共512 bit)划分为一个数据块,然后对数据块进行如下处理:

/* 处理每个16字数据块,共有(i=N/16)个 数据块 */
   For i = 0 to N/16-1 do

     /* 复制数据块i到 X(16元素的字数组),X为目标机器端格式(小端/大端) */
     For j = 0 to 15 do
       Set X[j] to M[i*16+j].	/*M为小端格式,复制到X时注意格式转换*/
     end /* j上的循环 */

     /* 将A保存为AA, B保存为BB, C保存为CC, 和D保存为DD */
     AA = A
     BB = B
     CC = C
     DD = D

     /* 第一轮 */
     /* 用 [abcd k s i] 表示操作
          a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
     /* 执行以下16个操作 */
     [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]

     /* 第二轮 */
     /* 用 [abcd k s i] 表示操作
          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
     /* 执行以下16个操作 */
     [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]

     /* 第三轮 */
     /* 用 [abcd k s i] 表示操作
          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
     /* 执行以下16个操作 */
     [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]

     /* 第四轮 */
     /* 用 [abcd k s i] 表示操作
          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
     /* 执行以下16个操作 */
     [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]

     /* 然后执行以下加法。 (也就是说,这四个寄存器的每一个都要加上它在这
        个数据块开始处理之前的旧值。) */
     A = A + AA
     B = B + BB
     C = C + CC
     D = D + DD

   end /* i上的循环 */

步骤5——输出

  作为输出产生的消息摘要是A、B、C、D。也就是说,从A的低字节开始,到D的高字节结束

在这里插入图片描述

  这样就完成了对MD5的描述。

猜你喜欢

转载自blog.csdn.net/weixin_44567318/article/details/113060931