Order

In the previous article, we introduced the most basic coding method--base64, and also briefly mentioned the principle of coding. This article continues to decrypt the series, of course, is also the introduction of a comparative basis of the encryption method--md5,md5 is a one-way encryption algorithm, is irreversible encryption, that is, the use of encryption MD5 encryption, you can not decrypt the results of the encryption, to get the original string, which is not possible.

Background

Believe that in our life, the MD5 use is still very extensive. Before you say MD5, let's start by understanding what one-way encryption algorithms are. Of course, MD5 is one of them, besides, Sha,hmac and other algorithms. However, today this article, we only introduce MD5, as for SHA and HMAC in the subsequent articles will be introduced in succession.

Body

MD5, all called "Message Digest algorithm 5", Chinese name "MSG Digest algorithm Fifth Edition", is a widely used hashing function in the field of computer security to provide integrity protection of messages. Strictly speaking, it is a digest algorithm, which ensures the integrity of information. However, in a sense, it can also be counted as a cryptographic algorithm.

The MD5 algorithm has many features:

- Compressibility: Any length of data, the calculated length of the MD5 value is fixed.
- Easy to calculate: It is easy to calculate the MD5 value from the original data.
- Anti-modification: Make any changes to the original data, even if only 1 bytes are modified, the resulting MD5 value is very different.
- Weak anti-collision: known raw data and its MD5 value, it is very difficult to find a data with the same MD5 value (that is, forgery data).
- Strong anti-collision: It is very difficult to find two different data so that they have the same MD5 value.

MD5 's role is to allow bulk information to be "compressed" into a confidential format before signing a private key with a digital signature software (that is, converting an arbitrary-length byte string into a long hexadecimal string).

MD5 in our life is very common, it seems you did not notice, when you download a mirror, you will find that the download page also provides a set of MD5 values, then this set of MD5 value is used to do? After understanding the role of MD5, it is not difficult to think that MD5 is used to verify the consistency of the file, when you download the image, you need to do a MD5 verification of the image, the resulting MD5 value and the download page provides a comparison of the MD5 value to verify that the image has been tampered with.

Why is it possible for MD5 to perform a consistency check?

In fact, MD5 and human fingerprints, everyone's fingerprints are unique, and the file's MD5 value is unique. And why is that? Let's take a look at how MD5 works.

The brief description of the MD5 algorithm can be: MD5 with 512-bit grouping to process the input information, and each grouping is divided into 16 32-bit sub-groups, after a series of processing, the output of the algorithm is composed of four 32-bit groupings, the four 32-bit grouping cascade will generate a 128-bit hash value.

The overall process, as shown, represents the group I, each time the operation is performed by the previous round of the 128-bit result value and block I the value of a bit.

Fill

In the MD5 algorithm, the first need to fill the information, so that its bit length to 512 the result of the remainder is equal to 448, and the fill must be carried out, even if its bit length to 512 to find the result equals 448. Therefore, the bit length (bits length) of the information will be extended to n * + 448,n as a nonnegative integer and n can be zero.

The padding method is as follows: 1) fill in a 1 and countless 0 after the information, until the above conditions are met, and then stop using the 0 padding for the information. 2) After this result, append a 64-bit binary representation of the pre-fill information length (in bits), if twoThe binary representation of the pre-fill information is longer than 64 bits, then the lower 64 bits are taken.

With this two-step process, the bit length of the information = n * + + 448 + = (n + 1) * 512, which is exactly the integer multiple of 512. The reason for this is to meet the information length requirements in the later processing.

Initialize Variables

The initial 128-bit value is the preliminary link variable, which is used for the first round of operations, denoted by the big endian byte order: A = 0x01234567,b = 0x89abcdef,c = 0xfedcba98,d = 0x76543210.

(the value given for each variable is the high byte stored in the low memory address, the low byte is stored in the memory high address, that is, the big endian byte order.) The values for variables A, B, C, and D in the program are 0x67452301,0xefcdab89,0x98badcfe,0x10325476 respectively)

working with grouped data

the algorithm flow for each grouping is as follows:

The first group needs to copy the above four link variables into the other four variables: A to A, b to B,c to C,d to D. The variable starting from the second group is the result of the previous grouping, i.e. A = A, B = b, c = c, d = d.

The main loop has four rounds, each with a similar cycle. The first round operates 16 times. Each operation makes a nonlinear function operation on three of them in A, B, C, and D, and then adds the resulting result to the fourth variable, a sub-group of text, and a constant. The resulting result is then shifted to Zoo by an indefinite number, plus one of a, B, C, or D. Finally, replace one of a, B, C or D with this result.

Output

The final output is the cascade of A, B, C, and D.

Code

Here is a Java version of the implementation, but it should be explained that the Java implementation of the English MD5 is not a problem, but for the Chinese will be a bit problematic, so the recommendation is only as a study for the purpose of reference. If it is a production requirement in your project, select the MD5 encryption function that comes with your JDK.

<span style = "font-family: Arial; font-size: 12px;"> package com.sica.md5.impl;
/ **
* Created by xiang.li on 2015/2/26.
* /
public class MD5 {
/ **
* Singleton
* /
private static MD5 instance;
/ **
* Four linked variables
* /
private final int A = 0x67452301;
private final int B = 0xefcdab89;
private final int C = 0x98badcfe;
private final int D = 0x10325476;
/ **
* ABCD temporary variables
* /
private int Atemp;
private int Btemp;
private int Ctemp;
private int Dtemp;
/ **
* Constant ti
* Formula: floor (abs (sin (i + 1)) × (2pow32)
* /
private final int [] K = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8,
0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193,
0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51,
0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905,
0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681,
0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60,
0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244,
0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314,
0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
};
/ **
* Shift to the left, calculation method is unknown
* /
private final int [] s = {
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7,
12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10,
15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
};
/ **
* Private constructor
* /
private MD5 () {
}
/ **
* Singleton mode
* @return
* /
public static MD5 getInstance () {
if (instance == null) {
instance = new MD5 ();
}
return instance;
}
/ **
* Initialization function
* /
private void init () {
Atemp = A;
Btemp = B;
Ctemp = C;
Dtemp = D;
}
/ **
* Move a certain number of digits
* @param a
* @param s
* @return
* /
private int shift (int a, int s) {
return (a << s) | (a >>> (32-s)); // When shifting right, the high-order bits must be padded with zeros, not the sign
}
/ **
* Main loop
* @param M
* /
private void mainLoop (int [] M) {
int F;
int g;
int a = Atemp;
int b = Btemp;
int c = Ctemp;
int d = Dtemp;
for (int i = 0; i <64; i ++) {
if (i <16) {
F = (b & c) | ((~ b) & d);
g = i;
} else if (i <32) {
F = (d & b) | ((~ d) & c);
g = (5 * i + 1)% 16;
} else if (i <48) {
F = b ^ c ^ d;
g = (3 * i + 5)% 16;
} else {
F = c ^ (b | (~ d));
g = (7 * i)% 16;
}
int tmp = d;
d = c;
c = b;
b = b + shift (a + F + K [i] + M [g], s [i]);
a = tmp;
}
Atemp + = a;
Btemp + = b;
Ctemp + = c;
Dtemp + = d;
}
/ **
* Fill function
* After processing, it should satisfy bits≡448 (mod512), and bytes is bytes≡56 (mode64)
* The padding method is to add a 0 first, and pad the other bits to zero.
* Finally add the original length of 64 bits
* @param str
* @return
* /
private int [] add (String str) {
int num = ((str.length () + 8) / 64) + 1; // 512 bits, 64 bytes as a group
int [] strByte = new int [num * 16]; // 64/4 = 16, so there are 16 integers
for (int i = 0; i <num * 16; i ++) {
// all initialized to 0
strByte [i] = 0;
}
int j;
for (j = 0; j <str.length (); j ++) {
strByte [j >> 2] | = str.charAt (j) << ((j% 4) * 8); // An integer stores four bytes, little-endian
}
strByte [j >> 2] | = 0x80 << ((j% 4) * 8); // add 1 at the end
// Add the original length, the length refers to the length of the bit, so multiply by 8, then the little-endian order, so put it in the penultimate one, here only 32 bits are used
strByte [num * 16-2] = str.length () * 8;
return strByte;
}
/ **
* Call functions
* @param source raw string
* @return
* /
public String getMD5 (String source) {
// initialization
init ();
int [] strByte = add (source);
for (int i = 0; i <strByte.length / 16; i + = 16) {
int [] num = new int [16];
for (int j = 0; j <16; j ++) {
num [j] = strByte [i * 16 + j];
}
mainLoop (num);
}
return changeHex (Atemp) + changeHex (Btemp) + changeHex (Ctemp) + changeHex (Dtemp);
}
/ **
* Integer becomes hexadecimal string
* @param a integer
* @return
* /
private String changeHex (int a) {
String str = "";
String tmp = "";
for (int i = 0; i <4; i ++) {
tmp = Integer.toHexString (((a >> i * 8)% (1 << 8)) & 0xff);
if (tmp.length (
) <2) {
tmp = "0" + tmp;
}
str + = tmp;
}
return str;
}
/ **
* testing method
* @param args
* /
public static void main (String [] args) {
String str = MD5.getInstance (). GetMD5 ("");
String str1 = MD5.getInstance (). GetMD5 ("123");
System.out.println (str);
System.out.println ("d41d8cd98f00b204e9800998ecf8427e");
System.out.println (str1);
System.out.println ("202cb962ac59075b964b07152d234b70");
}
} </ span> <span style = "font-family: Microsoft Yahei; font-size: 14px;">
</ span>

Conclusion

Perhaps you often see MD5, but you have never noticed, in the end what is MD5. Or maybe you know what a MD5 is, but maybe you don't know what MD5 is for. Well, from today onwards, from the time you read this blog, I believe that when you see MD5 later, you will certainly be impressed with it, and then download the file, it will be MD5 consistency check. Well, I can say that my article has played a little bit of a role.

The MD5 of the Java encryption and decryption technology series