知道的越多,不知道的越多

0%

MD5算法原理

要点

  • 任意长度的数据经过加密得到的MD5数据长度都是固定的。
  • 对原数据进行微小的改动,的到的MD5数据都有很大的区别。
  • 得到原数据和其MD5值,要找出一个具有相同MD5值的数据是非常困难的。

应用

  • 一致性验证: 为文件提供“数字指纹”,进行文件校验,如果有人对文件进行了修改,这个“指纹”就会发生变化,确保下载到的文件与站点文件是一致的。
  • 安全访问认证: 在需要登录验证的系统中,将用户密码经过MD5加密后存储在数据库中,在用户登录时将输入的密码进行加密后与数据库比对。
  • 数字签名: 在双方文件传输时,进行数字签名,防止文件被篡改、交易中抵赖的情况发生。

算法过程

一、填充

对字符串进行MD5加密,需要将字符串的处理人手。MD5是以512位进行分组进行处理的,所以需要将字符串长度需要能够整除512位。所以当无法整除的需要进行填充,假设R是余下的位数,则需要填充的情况总的有以下三种:

  • R = 0 : 此时需要填充一个512位分组,因为后面还要加入64位来记录填充前字符串长度。
  • R < 448 : 此时只需要填充到余数为448位就好,后面的64位用来记录长度。
  • R > 448 : 此时除了将这一组填充到512位后,还需要重新增加一组512位,为64位记录长度开辟空间。

填充步骤如下:

  1. 在信息后面先填充一个1,其余填充0,知道满足长度除以512余数为448位;
  2. 在结果后面附加64位长度的二进制,记录填充前信息的长度,如果二进制表示的填充前信息长度超过64位,则取低64位。

经过上面两个步骤之后,信息位长恰好是512位的整数倍,方便后面进行数据处理。

二、链接变量

初始的128位值位初始链接变量,这四个参数使用于第一轮运算,以大端字节序来表示。

1
2
3
4
A = 0x01234567
B = 0x89ABCDEF
C = 0xFEDCBA98
D = 0x76543210

三、四轮循环运算

每一轮循环都是以512位分组进行的,循环的次数即为分组的个数。第一分组需要将上面四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。从第二分组开始的变量为上一分组的运算结果,即A = a,B = b,C = c,D = d。

  1. 四个非线性函数:
    &是与,|是或,~是非,^是异或。

    1
    2
    3
    4
    F(X,Y,Z)=(X&Y)|((~X)&Z)
    G(X,Y,Z)=(X&Z)|(Y&(~Z))
    H(X,Y,Z)=X^Y^Z
    I(X,Y,Z)=Y^(X|(~Z))
  2. 设Mj表示消息的第j个子分组(从0到15),<<<s表示循环左移s位,常数ti是4294967296*abs( sin(i) )的整数部分,i 取值从1到64,单位是弧度。(4294967296=232),则四种操作为:

    1
    2
    3
    4
    FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)
    GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<<<s)
    HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<<<s)
    II(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<<<s)
  3. 四轮运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 第一轮
a=FF(a,b,c,d,M0,7,0xd76aa478)
b=FF(d,a,b,c,M1,12,0xe8c7b756)
c=FF(c,d,a,b,M2,17,0x242070db)
d=FF(b,c,d,a,M3,22,0xc1bdceee)
a=FF(a,b,c,d,M4,7,0xf57c0faf)
b=FF(d,a,b,c,M5,12,0x4787c62a)
c=FF(c,d,a,b,M6,17,0xa8304613)
d=FF(b,c,d,a,M7,22,0xfd469501)
a=FF(a,b,c,d,M8,7,0x698098d8)
b=FF(d,a,b,c,M9,12,0x8b44f7af)
c=FF(c,d,a,b,M10,17,0xffff5bb1)
d=FF(b,c,d,a,M11,22,0x895cd7be)
a=FF(a,b,c,d,M12,7,0x6b901122)
b=FF(d,a,b,c,M13,12,0xfd987193)
c=FF(c,d,a,b,M14,17,0xa679438e)
d=FF(b,c,d,a,M15,22,0x49b40821)

// 第二轮
a=GG(a,b,c,d,M1,5,0xf61e2562)
b=GG(d,a,b,c,M6,9,0xc040b340)
c=GG(c,d,a,b,M11,14,0x265e5a51)
d=GG(b,c,d,a,M0,20,0xe9b6c7aa)
a=GG(a,b,c,d,M5,5,0xd62f105d)
b=GG(d,a,b,c,M10,9,0x02441453)
c=GG(c,d,a,b,M15,14,0xd8a1e681)
d=GG(b,c,d,a,M4,20,0xe7d3fbc8)
a=GG(a,b,c,d,M9,5,0x21e1cde6)
b=GG(d,a,b,c,M14,9,0xc33707d6)
c=GG(c,d,a,b,M3,14,0xf4d50d87)
d=GG(b,c,d,a,M8,20,0x455a14ed)
a=GG(a,b,c,d,M13,5,0xa9e3e905)
b=GG(d,a,b,c,M2,9,0xfcefa3f8)
c=GG(c,d,a,b,M7,14,0x676f02d9)
d=GG(b,c,d,a,M12,20,0x8d2a4c8a)

// 第三轮
a=HH(a,b,c,d,M5,4,0xfffa3942)
b=HH(d,a,b,c,M8,11,0x8771f681)
c=HH(c,d,a,b,M11,16,0x6d9d6122)
d=HH(b,c,d,a,M14,23,0xfde5380c)
a=HH(a,b,c,d,M1,4,0xa4beea44)
b=HH(d,a,b,c,M4,11,0x4bdecfa9)
c=HH(c,d,a,b,M7,16,0xf6bb4b60)
d=HH(b,c,d,a,M10,23,0xbebfbc70)
a=HH(a,b,c,d,M13,4,0x289b7ec6)
b=HH(d,a,b,c,M0,11,0xeaa127fa)
c=HH(c,d,a,b,M3,16,0xd4ef3085)
d=HH(b,c,d,a,M6,23,0x04881d05)
a=HH(a,b,c,d,M9,4,0xd9d4d039)
b=HH(d,a,b,c,M12,11,0xe6db99e5)
c=HH(c,d,a,b,M15,16,0x1fa27cf8)
d=HH(b,c,d,a,M2,23,0xc4ac5665)

// 第四轮
a=II(a,b,c,d,M0,6,0xf4292244)
b=II(d,a,b,c,M7,10,0x432aff97)
c=II(c,d,a,b,M14,15,0xab9423a7)
d=II(b,c,d,a,M5,21,0xfc93a039)
a=II(a,b,c,d,M12,6,0x655b59c3)
b=II(d,a,b,c,M3,10,0x8f0ccc92)
c=II(c,d,a,b,M10,15,0xffeff47d)
d=II(b,c,d,a,M1,21,0x85845dd1)
a=II(a,b,c,d,M8,6,0x6fa87e4f)
b=II(d,a,b,c,M15,10,0xfe2ce6e0)
c=II(c,d,a,b,M6,15,0xa3014314)
d=II(b,c,d,a,M13,21,0x4e0811a1)
a=II(a,b,c,d,M4,6,0xf7537e82)
b=II(d,a,b,c,M11,10,0xbd3af235)
c=II(c,d,a,b,M2,15,0x2ad7d2bb)
d=II(b,c,d,a,M9,21,0xeb86d391)

所有这些完成之后,将a、b、c、d分别在原来基础上再加上A、B、C、D。
即a = a + A,b = b + B,c = c + C,d = d + D
然后用下一分组数据继续运行以上算法。

4.输出
最后的输出是a、b、c、d的级联。

欢迎关注我的其它发布渠道