[Inconsistency of MD5 encryption results] The same text string, after using MD5 encryption, the encryption results obtained are actually different

Table of contents

1.1. Error description

1.2. Solutions

1.3, MD5 tools


1.1. Error description

At work today, I encountered a strange problem. I was in charge of connecting to the third-party SMS sending interface. One of the input parameters in the interface was the sign plus field, which was obtained after MD5 encryption according to the content of the SMS, so I used the one that comes with JDK
. MD5 encryption algorithm, wrote an encryption method, the code is as follows:

package com.gitcode.demo.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;

/**
 * @version 1.0.0
 * @Date: 2023/8/24 10:41
 * @Author ZhuYouBin
 * @Description: MD5 加密工具类
 */
public class MD5Util {
    private static final Logger logger = LoggerFactory.getLogger(MD5Util.class);

    /**
     * 使用MD5加密
     * @param raw 明文
     */
    public static String encryptByJdk(String raw) {
        try {
            logger.info("MD5加密之前内容: {}", raw);
            if (raw == null || "".equals(raw.trim())) {
                return null;
            }
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] inputBytes = raw.getBytes();
            byte[] hashedBytes = md.digest(inputBytes);
            StringBuilder sb = new StringBuilder();
            for (byte b : hashedBytes) {
                sb.append(String.format("%02x", b));
            }
            logger.info("MD5加密之后内容: {}", sb);
            return sb.toString();
        } catch (Exception e) {
            logger.error("MD5加密异常:", e);
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String msg = "短信测试内容";
        encryptByJdk(msg);
    }
}

So I started to call the interface, hey, it failed, and then I asked the person in charge of the interface to consider whether the encryption result of MD5 was different, so the other party gave me an online encryption tool, let me compare the encryption results to see if the result is the same, address: https ://c.runoob.com/front-end/703/. The result encrypted using this tool is really different from the MD5 encryption result of JDK, as shown in the figure below.

Strange, I wonder if there is a problem with JDK's MD5 encryption, so I just asked the MD5 encryption algorithm provided by Spring to rewrite the code:

package com.gitcode.demo.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;

/**
 * @version 1.0.0
 * @Date: 2023/8/24 10:41
 * @Author ZhuYouBin
 * @Description: MD5 加密工具类
 */
public class MD5Util {
    private static final Logger logger = LoggerFactory.getLogger(MD5Util.class);

    /**
     * 使用MD5加密
     * @param raw 明文
     */
    public static String encrypt(String raw) {
        try {
            logger.info("MD5加密之前内容: {}", raw);
            if (raw == null || "".equals(raw.trim())) {
                return null;
            }
            String md5 = DigestUtils.md5DigestAsHex(raw.getBytes());
            logger.info("MD5加密之后内容: {}", md5);
            return md5;
        } catch (Exception e) {
            logger.error("MD5加密异常:", e);
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String msg = "短信测试内容";
        encrypt(msg);
    }
}

No accident, there will be an accident. The result of encryption is still different. I checked some blog posts later and found that it is an encoding problem. My IDEA uses GBK encoding. I changed the encoding to UTF-8, encrypted it again, and found that it worked, but it didn’t work, and there was no IDEA in the live environment. In the end, it was necessary to specify the character set encoding when calling the [getBytes()] method. .

1.2. Solutions 

When MD5 is encrypted, the specified character set encoding needs to be displayed. When calling the [getBytes()] method, specify the character set encoding. Generally, UTF-8 encoding is sufficient, as shown below:

getBytes(StandardCharsets.UTF_8)

// 或者
getBytes("UTF-8")

1.3, MD5 tools

package com.gitcode.demo.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;

import java.security.MessageDigest;

/**
 * @version 1.0.0
 * @Date: 2023/8/24 10:41
 * @Author ZhuYouBin
 * @Description: MD5 加密工具类
 */
public class MD5Util {
    private static final Logger logger = LoggerFactory.getLogger(MD5Util.class);

    /**
     * 使用MD5加密
     * @param raw 明文
     */
    public static String encrypt(String raw) {
        try {
            logger.info("MD5加密之前内容: {}", raw);
            if (raw == null || "".equals(raw.trim())) {
                return null;
            }
            String md5 = DigestUtils.md5DigestAsHex(raw.getBytes(StandardCharsets.UTF_8));
            logger.info("MD5加密之后内容: {}", md5);
            return md5;
        } catch (Exception e) {
            logger.error("MD5加密异常:", e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用MD5加密
     * @param raw 明文
     */
    public static String encryptByJdk(String raw) {
        try {
            logger.info("JDK中的MD5加密之前内容: {}", raw);
            if (raw == null || "".equals(raw.trim())) {
                return null;
            }
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] inputBytes = raw.getBytes(StandardCharsets.UTF_8);
            byte[] hashedBytes = md.digest(inputBytes);
            StringBuilder sb = new StringBuilder();
            for (byte b : hashedBytes) {
                sb.append(String.format("%02x", b));
            }
            logger.info("JDK中的MD5加密之后内容: {}", sb);
            return sb.toString();
        } catch (Exception e) {
            logger.error("MD5加密异常:", e);
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String msg = "短信测试内容";
        encrypt(msg);
        encryptByJdk(msg);
    }
}

At this point, the problem of inconsistent MD5 encryption results is solved. The root cause is that the character sets used are inconsistent . In fact, the encryption methods using JDK and Spring are the same, but the same encoding character set must be used.

Guess you like

Origin blog.csdn.net/qq_39826207/article/details/132482211