"MD5" encryption algorithm full analysis


"MD5" encryption algorithm full analysis

    Hello everyone, we will now explain the knowledge about encryption. When it comes to encryption, I think I have to mention MD5, because this is a special encryption method. What is it special? Now we will start to learn it

    Full name: message-digest algorithm 5
    The translation is: message digest algorithm 5

    1. Features

    • 1. Fixed length :

      No matter how long the string is, the length after encryption is the same . It
      is convenient for statistics and management of usual information.

    • 2. Easy to calculate :

      The process of string and file encryption is easy.
      Function: It is easy for developers to understand and make encryption tools

    • 3. Subtlety

      A file, no matter how big it is, as small as a few k or as large as a few G, as long as you change a character in it, the MD5 value will change .
      Function: Many software and applications provide download resources on the website, which contain the MD5 of the file. After downloading , the user only needs to use the tool to test the downloaded file , and through comparison, we can know whether the file has been changed or not .

    • 4. Irreversibility

      You clearly know the ciphertext and encryption method , but you cannot calculate the original password in reverse .
      Function: Based on this feature, many secure encryption methods are used. This greatly improves data security.


    2. Follow-up explanation

    • About credential stuffing cracking:

      This is a very low probability cracking method, the principle is:

      1. Build a large database , encrypt the daily sentences into ciphertext through MD5 , and continuously accumulate a large number of sentences and put them in a huge database.

      2. For example, if a person gets someone else's ciphertext and wants to query the real password , he needs to go to the website of the company that provides the database to query the ciphertext .

      This is the concept of credential stuffing.


    3. About MD5 salting:

    For example, my bank password is "12345"

    1. The obtained MD5 is: 827ccb0eea8a706c4c34a16891f84e7b

    2. If a person intercepts this ciphertext, then it is easy to knock out 12345 through credential bumping.

    3. All we have to do is add salt, the bank password is still "12345", and then I add the bank password to my specific string to calculate the MD5
    , so the password is still the same password, but it becomes the MD5 that asks for "12345 password encryption 987" value, and then get the MD5, then this MD5 can at least confirm that the database will not have it.


    Having said all that, let's start making our MD5 tool

    We generally encrypt strings or files, so our tool has two methods for encrypting strings and files. The two methods have the same name and are completed by overloading.

    1. Encrypt the string

    logical thinking:

    • 1. Get the information summary object: md5

      Obtained through the constructor of the information summary singleton :

      MessageDigest md5 = MessageDigest.getInstance("MD5");
      
            
            
      • 1
      • 2
    • 2. The information digest object is to digest the byte array , so first get the byte array of the string .

      byte[] bytes = str.getBytes();
      
            
            
      • 1
      • 2
    • 3. The message digest object digests the byte array to get the digest byte array :

      byte[] digest = md5.digest(bytes);
      
            
            
      • 1
      • 2
    • 4. Convert each byte in the summary array to hexadecimal, and put them together to get the MD5 value.
      (PS, some conversions get 6 f in front, such as: ffffff82 , this is Because there are 6 groups of 4 1s in front , it is good to change these 6 groups of 1111 to 0 in advance , and then convert to hexadecimal, there will be no f)
      (in fact, you can also remove f later)


    2. Encrypted files

    The method passed in is the file object: file

    • 1. Because it is a file and not a method, it is not to get the string through the digest like just now .

    • 2. You can use another method: the information summary object update : md5.update(byte[] input) method, the usage is to continuously update the "information array" read from the stream by reading the stream .

    • 3. Then get the digest through the "information digest object" without parameters: md5.digest() , the returned array is already the digest array containing the content


    The following is the detailed code:

    public class MD5Tool {
        public static void main(String[] args) throws Exception {
            /*--------------字符串--------------*/
            String str = "12345";
            String md1 = getMD5(str);
            System.out.println(md1);//827ccb0eea8a706c4c34a16891f84e7b
    
            /*--------------文件--------------*/
            File file = new File("D:\\1.mp3");
            String md2 = getMD5(file);
            System.out.println(md2);//9068aaead9a5b75e6a54395d8183ec9
        }
        /**
         * 逻辑:
         *
         * 1.获取md5对象,通过"信息摘要"获取实例构造("MD5").
         * 2.md5对象对("字符串的"字节形式"-得到的数组)进行摘要",那么会返回一个"摘要的字节数组"
         * 3.摘要字节数组中的"每个二进制值"字节形式,"转成十六进制形式",然后再把这些值给拼接起来,就是MD5值了
         *      (PS:为了便于阅读,把多余的fff去掉,并且单个字符前加个0)
         *
         */
        public static String getMD5(String str) throws Exception {
    
            String MD5 = "";
    
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = str.getBytes();
            byte[] digest = md5.digest(bytes);
    
            for (int i = 0; i < digest.length; i++) {
                //摘要字节数组中各个字节的"十六进制"形式.
                int j = digest[i];
                 j = j & 0x000000ff;
                String s1 = Integer.toHexString(j);
    
                if (s1.length() == 1) {
                    s1 = "0" + s1;
                }
                MD5 += s1;
            }
            return MD5;
        }
        //重载,所以用户传入"字符串"或者"文件"都可以解决.
    
        /**
         * 处理逻辑:
         * 1.现在传入的是"文件",不是字符串
         * 2.所以信息摘要对象.进行摘要得到数组不能像上面获得:md5.digest(bytes),因为不是str.getBytes得到bytes
         * 3.其实还是通过mdt.digest();获取到字节数组,但是前期必须要有一个方法必须是md5.update(),即"信息摘要对象"要先更新
         * 4."信息摘要更新"里面有(byte[] input),说明是读取流获取到的数组,所以我们就用这个方法.
         * 5.所以最终的逻辑就是:
         *
         *      1.获取文件的读取流
         *      2.不停的读取流中的"内容"放入字符串,放一部分就"更新"一部分.直到全部完毕
         *      3.然后调用md5.digest();就会得到有内容的字节数组,剩下的就和上边一样了.
         */
        public static String getMD5(File file) throws Exception {
            String MD5 = "";
    
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            FileInputStream fis = new FileInputStream(file);
    
            byte[] bytes = new byte[1024 * 5];
    
            int len = -1;
            while ((len=fis.read(bytes))!=-1) {
                //一部分一部分更新
                md5.update(bytes, 0, len);
            }
            byte[] digest = md5.digest();
            for (int i = 0; i <digest.length; i++) {
                int n = digest[i] & 0x000000ff;
                String s = Integer.toHexString(n);
    
                MD5 += s;
            }
            return MD5;
        }
    }
        
        
    • 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

    expand

    The meaning of 0xffffffff:


    • 0x: represents hexadecimal;

    • An f represents: 4 1s , ie (1111);

    • So 0xffffffff means: 8 groups of 4 1s

    1111 - 1111 - 1111 - 1111 - 1111 - 1111 - 1111 - 1111 
    
    
        
        
    • 1
    • 2
  • So the 0xffffff82 just now means that the first six groups are all 1, and the last two groups are

  • 1111 - 1111 - 1111 - 1111 - 1111 - 1111 - 0111 - 0010 
    
    
        
        
    • 1
    • 2
  • So first with 0x000000ff, that is

0000 - 0000 - 0000 - 0000 - 0000 - 0000 - 1111 - 1111
  • I got 82

The above method can also be written as:


   for (int i = 0; i < digest.length; i++) {
            //摘要字节数组中各个字节的"十六进制"形式.
            String s1 = Integer.toHexString( digest[i]);

            //如果是8个长度的,把前面的6个f去掉,只获取后面的
            if (s1.length() == 8) {
                s1 = s1.substring(6);
            }
            if (s1.length() == 1) {
                s1 = "0" + s1;
            }
            MD5 += s1;
        }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326227211&siteId=291194637