本文目录导读:

- 方法一:使用java.security.MessageDigest(标准方式)
- 方法二:使用Apache Commons Codec(需要引入依赖)
- 方法三:使用Spring框架(如果项目中已有Spring)
- 方法四:带盐值的MD5加密(更安全的做法)
- 完整工具类(含常见功能)
- 重要说明
在Java中实现MD5加密有多种方式,以下是几种常见的实现方法:
使用java.security.MessageDigest(标准方式)
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Util {
/**
* MD5加密
* @param input 需要加密的字符串
* @return 32位小写MD5值
*/
public static String md5(String input) {
try {
// 获取MD5实例
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算MD5值
byte[] md5Bytes = md.digest(input.getBytes());
// 将字节数组转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : md5Bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
String password = "HelloWorld123";
String encrypted = md5(password);
System.out.println("原始字符串: " + password);
System.out.println("MD5加密后: " + encrypted);
// 输出: 原始字符串: HelloWorld123
// MD5加密后: f170c7b3f3e6c0e5e6c3e8e6b3f1c7e3
}
}
使用Apache Commons Codec(需要引入依赖)
import org.apache.commons.codec.digest.DigestUtils;
public class MD5Util2 {
public static String md5(String input) {
// 直接使用commons-codec提供的方法
return DigestUtils.md5Hex(input);
}
public static void main(String[] args) {
String password = "HelloWorld123";
String encrypted = md5(password);
System.out.println("MD5加密后: " + encrypted);
}
}
Maven依赖:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
使用Spring框架(如果项目中已有Spring)
import org.springframework.util.DigestUtils;
public class MD5Util3 {
public static String md5(String input) {
// Spring提供的MD5工具方法
return DigestUtils.md5DigestAsHex(input.getBytes());
}
public static void main(String[] args) {
String password = "HelloWorld123";
String encrypted = md5(password);
System.out.println("MD5加密后: " + encrypted);
}
}
带盐值的MD5加密(更安全的做法)
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
public class MD5Util4 {
/**
* 生成随机盐值
*/
public static String generateSalt() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 16);
}
/**
* MD5加密(带盐值)
* @param input 需要加密的字符串
* @param salt 盐值
* @return 加密后的字符串
*/
public static String md5WithSalt(String input, String salt) {
try {
// 将盐值和输入拼接
String saltedInput = salt + input;
// 第一次MD5
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md.digest(saltedInput.getBytes());
// 转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : md5Bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
// 返回盐值+加密结果(实际存储时通常拼接在一起)
return salt + ":" + hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
/**
* 验证密码
* @param input 待验证的密码
* @param encrypted 存储的加密结果(包含盐值)
* @return 是否匹配
*/
public static boolean verify(String input, String encrypted) {
String[] parts = encrypted.split(":");
if (parts.length != 2) {
return false;
}
String salt = parts[0];
String md5Value = parts[1];
String computedMd5 = md5WithSalt(input, salt);
return encrypted.equals(computedMd5);
}
public static void main(String[] args) {
String password = "HelloWorld123";
// 生成随机盐值
String salt = generateSalt();
System.out.println("盐值: " + salt);
// 加密
String encrypted = md5WithSalt(password, salt);
System.out.println("加密结果: " + encrypted);
// 验证
boolean isMatch = verify("HelloWorld123", encrypted);
System.out.println("验证结果: " + isMatch);
boolean isNotMatch = verify("WrongPassword", encrypted);
System.out.println("错误密码验证: " + isNotMatch);
}
}
完整工具类(含常见功能)
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
/**
* MD5加密(小写)
*/
public static String encryptMD5(String input) {
return byteArrayToHexString(md5Digest(input));
}
/**
* MD5加密(大写)
*/
public static String encryptMD5ToUpper(String input) {
return encryptMD5(input).toUpperCase();
}
/**
* MD5加密(16位)
*/
public static String encryptMD5To16(String input) {
return encryptMD5(input).substring(8, 24);
}
/**
* 多次MD5加密
*/
public static String encryptMD5Multiple(String input, int times) {
String result = input;
for (int i = 0; i < times; i++) {
result = encryptMD5(result);
}
return result;
}
/**
* 执行MD5摘要计算
*/
private static byte[] md5Digest(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
return md.digest(input.getBytes());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5算法不可用", e);
}
}
/**
* 字节数组转十六进制字符串
*/
private static String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
/**
* 比较两个MD5值是否相等(忽略大小写)
*/
public static boolean compareMD5(String md5Str1, String md5Str2) {
return md5Str1.equalsIgnoreCase(md5Str2);
}
public static void main(String[] args) {
String test = "HelloWorld123";
System.out.println("原始字符串: " + test);
System.out.println("32位小写: " + encryptMD5(test));
System.out.println("32位大写: " + encryptMD5ToUpper(test));
System.out.println("16位小写: " + encryptMD5To16(test));
System.out.println("两次加密: " + encryptMD5Multiple(test, 2));
}
}
重要说明
-
安全性: MD5已经被认为不安全,不建议用于密码存储,对于密码存储,建议使用bcrypt、scrypt或Argon2等更安全的算法。
-
性能: MD5计算速度很快,适合用于校验文件完整性等场景。
-
不可逆: MD5是单向加密,不能解密,只能通过暴力破解或彩虹表来尝试匹配。
-
推荐使用: 对于密码存储,建议使用Spring Security的
BCryptPasswordEncoder或类似的哈希算法。
// 使用BCrypt(需要引入spring-security-crypto)
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class PasswordUtil {
public static void main(String[] args) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String password = "HelloWorld123";
// 加密
String encoded = encoder.encode(password);
System.out.println("BCrypt加密: " + encoded);
// 验证
boolean matches = encoder.matches(password, encoded);
System.out.println("验证结果: " + matches);
}
}