java 实现md5加密的三种方式与解密
一、解密
说明:截止文章发布,Java没有实现解密,但是已有网站可以免费破解了!(本质应该是将加密结果与加密前的数据对应存储起来了)
见文末相关推荐
二、加密的三种方式
说明:都是返回长度为32位的16进制字符串(小写)。
方法一:推荐使用
所需jar包:commons-codec.jar
import org.apache.commons.codec.digest.DigestUtils;
/**
* MD5加密之方法一
* @explain 借助apache工具类DigestUtils实现
* @param str
* 待加密字符串
* @return 16进制加密字符串
*/
public static String encryptToMD5(String str) {
return DigestUtils.md5Hex(str);
}
方法二
/**
* MD5加密之方法二
* @explain java实现
* @param str
* 待加密字符串
* @return 16进制加密字符串
*/
public static String encrypt2ToMD5(String str) {
// 加密后的16进制字符串
String hexStr = "";
try {
// 此 MessageDigest 类为应用程序提供信息摘要算法的功能
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 转换为MD5码
byte[] digest = md5.digest(str.getBytes("utf-8"));
hexStr = ByteUtils.toHexString(digest);
} catch (Exception e) {
e.printStackTrace();
}
return hexStr;
}
方法三:SPRING核心包
import org.springframework.util.DigestUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.UnsupportedEncodingException;
/**
* MD5加密
* @explain springboot自带MD5加密
* @param str 待加密字符串
* @return 16进制加密字符串
*/
public static String toMD5(String str) {
log.debug("MD5待加密字符串:\n" + str);
String md5 = "";
try {
md5 = DigestUtils.md5DigestAsHex(str.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
log.debug("MD5加密结果:\n" + md5);
return md5;
}
20200827
spring-core.jar,只要有这个jar包,就能引入DigestUtils.class。
这也是springboot能够引入该类的最终原因,比如说:我使用的是
鼠标悬浮,同时按住Ctrl键,点击就可以打开该jar包的.pom文件,你会发现有这样一个依赖
再次执行以上操作
我们可以发现:springboot最终依赖的有spring-core.jar,所以,springboot也可以直接导入DigestUtils.class
三、测试
public static void main(String[] args) { String str = "Marydon"; System.out.println("MD5加密方法一:" + MD5Utils.encryptToMD5(str)); System.out.println("MD5加密方法二:" + MD5Utils.encrypt2ToMD5(str)); System.out.println("MD5加密方法三:" + MD5Utils.encrypt3ToMD5(str)); // 结束都是:988218e7eefcd86d5d855a8947f37f43 }
四、关于md5自动补零
20201201
我们知道,MD5加密结果通常返回的是32位的16进制字符串,加密结果之所以永远是32位,其实是进行了自动补零操作(也就是:当加密结果长度不够32位时,会在前面自动补零,直到满足长度=32位)
下面就来验证一下:
如上图所示,两个加密结果都进行了补零操作。
它们的真实加密结果就是:去掉前面的0,一起来验证一下。
只所以讲这个问题,是因为在实际开发过程中,在对接接口的时候,我方用的是常用的MD5加密方案(自动补零),而接口提供方使用的是展示真实加密结果的MD5,在比对加密结果的时候肯定会经常出现加密结果不一致导致校验失败的问题。
所以,我在这里添加能够显示真实加密结果的MD5代码,以供有这种特殊需求的园友使用。
/*
* MD5加密(真实长度,不补零)
* @attention:
* @date: 2020年12月01日 0001 14:44
* @param: str
* @return: java.lang.String
*/
public static String toMD5_realLength_UpperCase(String str) {
if (StringUtils.isEmpty(str)) return "";
try {
log.debug("MD5待加密字符串:\n" + str);
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 计算md5函数
md5.update(str.getBytes(UTF8));
//digest()最后确定返回md5 hash值,返回值为8位字符串。
//因为md5hash值是16位的hex值,实际上就是8位的字符
//BigInteger函数则将8位的字符串转换成16位hex值,
//用字符串来表示;得到字符串形式的hash值
String md5Str = new BigInteger(1, md5.digest()).toString(16).toUpperCase();
log.debug("MD5加密结果(不补零):\n" + md5Str);
return md5Str;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
/*
* MD5加密(真实长度,不补零)
* @attention:
* @date: 2020年12月01日 0001 14:44
* @param: str
* @return: java.lang.String
*/
public static String toMD5_realLength_LowerCase(String str) {
if (StringUtils.isEmpty(str)) return "";
try {
log.debug("MD5待加密字符串:\n" + str);
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 计算md5函数
md5.update(str.getBytes(UTF8));
String md5Str = new BigInteger(1, md5.digest()).toString(16).toLowerCase();
log.debug("MD5加密结果(不补零):\n" + md5Str);
return md5Str;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
相关推荐:
- 解密网站:http://somd5.com/
- 解密网站2
- commons-codec-1.4.jar下载
- java byte数组与16进制间的相互转换