md5 加密算法
文章目录
-
md5 加密算法
-
1、背景
-
在很多比较重要的环境,我们的前端在传输
11`密码
11`时,不能以
11`明文
11`的形式传递,所以需要用一些加密算法进行加密,进而传输,且前后端的加密方式相同。
- 2、前端方法
- 3、后端算法
- 4、唯一性
-
为了保证我们的算法的唯一性,不被轻易撞到(算法完全相同,导致方法泄露)。
* 我们可以把K数组的一些变量修改。比如: -
js中
* java中1
21 * 可以看到,这里面的16进制数都是一一对应的,所以,如果出于安全考虑,我们可以将某一位(比如第一个),同时修改,来到达算法唯一的目的
2
1、背景
在很多比较重要的环境,我们的前端在传输密码时,不能以明文的形式传递,所以需要用一些加密算法进行加密,进而传输,且前后端的加密方式相同。
2、前端方法
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 1function md5(string) {
2 function md5_RotateLeft(lValue, iShiftBits) {
3 return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
4 }
5 function md5_AddUnsigned(lX, lY) {
6 var lX4, lY4, lX8, lY8, lResult;
7 lX8 = (lX & 0x80000000);
8 lY8 = (lY & 0x80000000);
9 lX4 = (lX & 0x40000000);
10 lY4 = (lY & 0x40000000);
11 lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
12 if (lX4 & lY4) {
13 return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
14 }
15 if (lX4 | lY4) {
16 if (lResult & 0x40000000) {
17 return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
18 } else {
19 return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
20 }
21 } else {
22 return (lResult ^ lX8 ^ lY8);
23 }
24 }
25 function md5_F(x, y, z) {
26 return (x & y) | ((~x) & z);
27 }
28 function md5_G(x, y, z) {
29 return (x & z) | (y & (~z));
30 }
31 function md5_H(x, y, z) {
32 return (x ^ y ^ z);
33 }
34 function md5_I(x, y, z) {
35 return (y ^ (x | (~z)));
36 }
37 function md5_FF(a, b, c, d, x, s, ac) {
38 a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_F(b, c, d), x), ac));
39 return md5_AddUnsigned(md5_RotateLeft(a, s), b);
40 };
41 function md5_GG(a, b, c, d, x, s, ac) {
42 a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_G(b, c, d), x), ac));
43 return md5_AddUnsigned(md5_RotateLeft(a, s), b);
44 };
45 function md5_HH(a, b, c, d, x, s, ac) {
46 a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_H(b, c, d), x), ac));
47 return md5_AddUnsigned(md5_RotateLeft(a, s), b);
48 };
49 function md5_II(a, b, c, d, x, s, ac) {
50 a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_I(b, c, d), x), ac));
51 return md5_AddUnsigned(md5_RotateLeft(a, s), b);
52 };
53 function md5_ConvertToWordArray(string) {
54 var lWordCount;
55 var lMessageLength = string.length;
56 var lNumberOfWords_temp1 = lMessageLength + 8;
57 var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
58 var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
59 var lWordArray = Array(lNumberOfWords - 1);
60 var lBytePosition = 0;
61 var lByteCount = 0;
62 while (lByteCount < lMessageLength) {
63 lWordCount = (lByteCount - (lByteCount % 4)) / 4;
64 lBytePosition = (lByteCount % 4) * 8;
65 lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
66 lByteCount++;
67 }
68 lWordCount = (lByteCount - (lByteCount % 4)) / 4;
69 lBytePosition = (lByteCount % 4) * 8;
70 lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
71 lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
72 lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
73 return lWordArray;
74 };
75 function md5_WordToHex(lValue) {
76 var WordToHexValue = "",
77 WordToHexValue_temp = "",
78 lByte, lCount;
79 for (lCount = 0; lCount <= 3; lCount++) {
80 lByte = (lValue >>> (lCount * 8)) & 255;
81 WordToHexValue_temp = "0" + lByte.toString(16);
82 WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
83 }
84 return WordToHexValue;
85 };
86 function md5_Utf8Encode(string) {
87 string = string.replace(/\r\n/g, "\n");
88 var utftext = "";
89 for (var n = 0; n < string.length; n++) {
90 var c = string.charCodeAt(n);
91 if (c < 128) {
92 utftext += String.fromCharCode(c);
93 } else if ((c > 127) && (c < 2048)) {
94 utftext += String.fromCharCode((c >> 6) | 192);
95 utftext += String.fromCharCode((c & 63) | 128);
96 } else {
97 utftext += String.fromCharCode((c >> 12) | 224);
98 utftext += String.fromCharCode(((c >> 6) & 63) | 128);
99 utftext += String.fromCharCode((c & 63) | 128);
100 }
101 }
102 return utftext;
103 };
104 var x = Array();
105 var k, AA, BB, CC, DD, a, b, c, d;
106 var S11 = 7,
107 S12 = 12,
108 S13 = 17,
109 S14 = 22;
110 var S21 = 5,
111 S22 = 9,
112 S23 = 14,
113 S24 = 20;
114 var S31 = 4,
115 S32 = 11,
116 S33 = 16,
117 S34 = 23;
118 var S41 = 6,
119 S42 = 10,
120 S43 = 15,
121 S44 = 21;
122 string = md5_Utf8Encode(string);
123 x = md5_ConvertToWordArray(string);
124 a = 0x67452301;
125 b = 0xEFCDAB89;
126 c = 0x98BADCFE;
127 d = 0x10325476;
128 for (k = 0; k < x.length; k += 16) {
129 AA = a;
130 BB = b;
131 CC = c;
132 DD = d;
133 a = md5_FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
134 d = md5_FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
135 c = md5_FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
136 b = md5_FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
137 a = md5_FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
138 d = md5_FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
139 c = md5_FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
140 b = md5_FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
141 a = md5_FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
142 d = md5_FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
143 c = md5_FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
144 b = md5_FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
145 a = md5_FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
146 d = md5_FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
147 c = md5_FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
148 b = md5_FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
149 a = md5_GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
150 d = md5_GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
151 c = md5_GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
152 b = md5_GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
153 a = md5_GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
154 d = md5_GG(d, a, b, c, x[k + 10], S22, 0x2441453);
155 c = md5_GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
156 b = md5_GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
157 a = md5_GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
158 d = md5_GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
159 c = md5_GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
160 b = md5_GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
161 a = md5_GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
162 d = md5_GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
163 c = md5_GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
164 b = md5_GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
165 a = md5_HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
166 d = md5_HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
167 c = md5_HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
168 b = md5_HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
169 a = md5_HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
170 d = md5_HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
171 c = md5_HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
172 b = md5_HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
173 a = md5_HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
174 d = md5_HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
175 c = md5_HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
176 b = md5_HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
177 a = md5_HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
178 d = md5_HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
179 c = md5_HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
180 b = md5_HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
181 a = md5_II(a, b, c, d, x[k + 0], S41, 0xF4292244);
182 d = md5_II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
183 c = md5_II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
184 b = md5_II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
185 a = md5_II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
186 d = md5_II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
187 c = md5_II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
188 b = md5_II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
189 a = md5_II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
190 d = md5_II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
191 c = md5_II(c, d, a, b, x[k + 6], S43, 0xA3014314);
192 b = md5_II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
193 a = md5_II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
194 d = md5_II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
195 c = md5_II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
196 b = md5_II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
197 a = md5_AddUnsigned(a, AA);
198 b = md5_AddUnsigned(b, BB);
199 c = md5_AddUnsigned(c, CC);
200 d = md5_AddUnsigned(d, DD);
201 }
202 return (md5_WordToHex(a) + md5_WordToHex(b) + md5_WordToHex(c) + md5_WordToHex(d)).toLowerCase();
203}
204
205
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 1public class MD5Util{
2 /*
3 *四个链接变量
4 */
5 private final int A=0x67452301;
6 private final int B=0xefcdab89;
7 private final int C=0x98badcfe;
8 private final int D=0x10325476;
9 /*
10 *ABCD的临时变量
11 */
12 private int Atemp,Btemp,Ctemp,Dtemp;
13
14 /*
15 *常量ti
16 *公式:floor(abs(sin(i+1))×(2pow32)
17 */
18 private final int K[]={
19 0xD76AA478,0xe8c7b756,0x242070db,0xc1bdceee,
20 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
21 0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
22 0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,
23 0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
24 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,
25 0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,
26 0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,
27 0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
28 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
29 0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
30 0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
31 0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391};
32 /*
33 *向左位移数,计算方法未知
34 */
35 private final int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,
36 12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
37 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
38 15,21,6,10,15,21,6,10,15,21,6,10,15,21};
39
40
41 /*
42 *初始化函数
43 */
44 private void init(){
45 Atemp=A;
46 Btemp=B;
47 Ctemp=C;
48 Dtemp=D;
49 }
50 /*
51 *移动一定位数
52 */
53 private int shift(int a,int s){
54 return(a<<s)|(a>>>(32-s));//右移的时候,高位一定要补零,而不是补充符号位
55 }
56 /*
57 *主循环
58 */
59 private void MainLoop(int M[]){
60 int F,g;
61 int a=Atemp;
62 int b=Btemp;
63 int c=Ctemp;
64 int d=Dtemp;
65 for(int i = 0; i < 64; i ++){
66 if(i<16){
67 F=(b&c)|((~b)&d);
68 g=i;
69 }else if(i<32){
70 F=(d&b)|((~d)&c);
71 g=(5*i+1)%16;
72 }else if(i<48){
73 F=b^c^d;
74 g=(3*i+5)%16;
75 }else{
76 F=c^(b|(~d));
77 g=(7*i)%16;
78 }
79 int tmp=d;
80 d=c;
81 c=b;
82 b=b+shift(a+F+K[i]+M[g],s[i]);
83 a=tmp;
84 }
85 Atemp=a+Atemp;
86 Btemp=b+Btemp;
87 Ctemp=c+Ctemp;
88 Dtemp=d+Dtemp;
89
90 }
91 /*
92 *填充函数
93 *处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
94 *填充方式为先加一个0,其它位补零
95 *最后加上64位的原来长度
96 */
97 private int[] add(String str){
98 int num=((str.length()+8)/64)+1;//以512位,64个字节为一组
99 int strByte[]=new int[num*16];//64/4=16,所以有16个整数
100 for(int i=0;i<num*16;i++){//全部初始化0
101 strByte[i]=0;
102 }
103 int i;
104 for(i=0;i<str.length();i++){
105 strByte[i>>2]|=str.charAt(i)<<((i%4)*8);//一个整数存储四个字节,小端序
106 }
107 strByte[i>>2]|=0x80<<((i%4)*8);//尾部添加1
108 /*
109 *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
110 */
111 strByte[num*16-2]=str.length()*8;
112 return strByte;
113 }
114 /*
115 *调用函数
116 */
117 public String getMD5(String source){
118 init();
119 int strByte[]=add(source);
120 for(int i=0;i<strByte.length/16;i++){
121 int num[]=new int[16];
122 for(int j=0;j<16;j++){
123 num[j]=strByte[i*16+j];
124 }
125 MainLoop(num);
126 }
127 return changeHex(Atemp)+changeHex(Btemp)+changeHex(Ctemp)+changeHex(Dtemp);
128
129 }
130 /*
131 *整数变成16进制字符串
132 */
133 private String changeHex(int a){
134 String str="";
135 for(int i=0;i<4;i++){
136 str+=String.format("%2s", Integer.toHexString(((a>>i*8)%(1<<8))&0xff)).replace(' ', '0');
137
138 }
139 return str;
140 }
141 /*
142 *单例
143 */
144 private static MD5Util instance;
145 public static MD5Util getInstance(){
146 if(instance==null){
147 instance=new MD5Util();
148 }
149 return instance;
150 }
151
152 private MD5Util(){};
153
154 public static void main(String[] args){
155 String str=MD5Util.getInstance().getMD5("ltz123");
156 System.out.println(str);
157 }
158}
159
160