【MD5加密结果不一致问题】同一个文本字符串,使用MD5加密之后,得出的加密结果居然不相同

目录

1.1、错误描述

1.2、解决方案

1.3、MD5工具类


1.1、错误描述

今天工作中,遇到一个奇怪的问题,我负责对接第三方的短信发送接口,接口中有一个入参是sign加签字段,根据短信内容进行MD5加密
之后得到,于是我就是使用JDK自带的MD5加密算法,写了一个加密方法,代码如下:

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);
    }
}

于是开始调用接口,哎,居然失败了,接着问接口负责人,考虑是不是MD5的加密结果不同,于是对方给了一个在线加密工具,让我对比下加密的结果是不是一样的,地址:https://c.runoob.com/front-end/703/。使用这个工具加密出来的结果,还真和JDK的MD5加密结果不一样,如下图所示。

奇了怪,我寻思是不是JDK的MD5加密有问题,于是我就是要Spring提供的MD5加密算法重新写了个代码:

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);
    }
}

不出意外,就要出意外,加密的结果还是不一样,后面查看了一些博客文章,发现是编码的问题,我的IDEA是使用的GBK编码。我把编码改成UTF-8,再次进行加密,发现居然可以了,但是这样也不行呀,发到现场环境又没有IDEA,最终是需要在调用【getBytes()】方法的时候,指定字符集编码。

1.2、解决方案 

MD5加密时候,需要显示的指定采用的字符集编码,在调用【getBytes()】方法时候,指定字符集编码,一般采用UTF-8编码就可以啦,如下所示:

getBytes(StandardCharsets.UTF_8)

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

1.3、MD5工具类

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);
    }
}

到此,MD5加密结果不一致的问题就解决啦,根本原因还是采用的字符集不一致,其实使用JDK和Spring的加密方法都一样,只不过要保证使用相同的编码字符集。

猜你喜欢

转载自blog.csdn.net/qq_39826207/article/details/132482211