md5 加密算法

释放双眼,带上耳机,听听看~!

md5 加密算法

文章目录

  • md5 加密算法

  • 1、背景

  • 在很多比较重要的环境,我们的前端在传输

    1
    1`

    密码

    1
    1`

    时,不能以

    1
    1`

    明文

    1
    1`

    的形式传递,所以需要用一些加密算法进行加密,进而传输,且前后端的加密方式相同。

    • 2、前端方法
    • 3、后端算法
    • 4、唯一性
  • 为了保证我们的算法的唯一性,不被轻易撞到(算法完全相同,导致方法泄露)。
    * 我们可以把K数组的一些变量修改。比如:

  • js中
    * java中

    
    
    1
    2
    1      * 可以看到,这里面的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

4、唯一性

为了保证我们的算法的唯一性,不被轻易撞到(算法完全相同,导致方法泄露)。

我们可以把K数组的一些变量修改。比如:

js中

md5 加密算法

java中

md5 加密算法

可以看到,这里面的16进制数都是一一对应的,所以,如果出于安全考虑,我们可以将某一位(比如第一个),同时修改,来到达算法唯一的目的

给TA打赏
共{{data.count}}人
人已打赏
安全技术安全运维

Windows服务器如何发现被黑

2018-5-20 12:24:31

安全技术

详解Node.js API系列C/C++ Addons(1) API文档

2021-12-21 16:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索