本文目录导读:

我来详细介绍Java中MD5加密的实操案例。
基础MD5加密实现
使用MessageDigest类(最常用)
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Util {
/**
* MD5加密基础方法
* @param str 待加密字符串
* @return 加密后的32位小写字符串
*/
public static String md5(String str) {
try {
// 创建MD5加密算法实例
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 将字符串转换为字节数组并更新摘要
byte[] digest = md5.digest(str.getBytes());
// 将字节数组转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
// 将字节转换为十六进制
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 = "hello123";
String encrypted = md5(password);
System.out.println("原始密码: " + password);
System.out.println("MD5加密: " + encrypted);
System.out.println("长度: " + encrypted.length());
}
}
带盐值的MD5加密
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class SaltedMD5Util {
/**
* 生成随机盐值
*/
public static String generateSalt() {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
return Base64.getEncoder().encodeToString(salt);
}
/**
* 带盐值的MD5加密
* @param password 原始密码
* @param salt 盐值
* @return 加密后的字符串
*/
public static String md5WithSalt(String password, String salt) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 将密码和盐值组合
md5.update(salt.getBytes());
byte[] digest = md5.digest(password.getBytes());
// 转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
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 boolean verify(String inputPassword, String storedPassword, String salt) {
String encryptedInput = md5WithSalt(inputPassword, salt);
return encryptedInput.equals(storedPassword);
}
public static void main(String[] args) {
String password = "mySecret123";
String salt = generateSalt();
String encryptedPassword = md5WithSalt(password, salt);
System.out.println("原始密码: " + password);
System.out.println("盐值: " + salt);
System.out.println("加密结果: " + encryptedPassword);
// 验证密码
boolean isMatch = verify("mySecret123", encryptedPassword, salt);
System.out.println("密码验证结果: " + isMatch);
// 测试错误密码
boolean isMatch2 = verify("wrongPassword", encryptedPassword, salt);
System.out.println("错误密码验证: " + isMatch2);
}
}
多次MD5加密(增强安全性)
import java.security.MessageDigest;
public class MultiMD5Util {
/**
* 多次MD5加密
* @param str 原始字符串
* @param times 加密次数
* @return 加密后的字符串
*/
public static String multiMd5(String str, int times) {
String result = str;
for (int i = 0; i < times; i++) {
result = md5(result);
}
return result;
}
/**
* 基础MD5加密
*/
private static String md5(String str) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] digest = md5.digest(str.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
String password = "hello123";
// 单次加密
String once = md5(password);
System.out.println("单次加密: " + once);
// 3次加密
String threeTimes = multiMd5(password, 3);
System.out.println("3次加密: " + threeTimes);
// 10次加密
String tenTimes = multiMd5(password, 10);
System.out.println("10次加密: " + tenTimes);
}
}
文件MD5校验
import java.io.*;
import java.security.MessageDigest;
public class FileMD5Util {
/**
* 计算文件的MD5值
* @param file 文件对象
* @return 文件的MD5值
*/
public static String getFileMD5(File file) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
md5.update(buffer, 0, bytesRead);
}
fis.close();
byte[] digest = md5.digest();
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
// 测试文件MD5
File file = new File("test.txt");
if (file.exists()) {
String fileMD5 = getFileMD5(file);
System.out.println("文件MD5值: " + fileMD5);
} else {
System.out.println("文件不存在");
}
}
}
实际应用示例(用户密码管理)
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
public class PasswordManager {
private Map<String, UserInfo> userDB = new HashMap<>();
// 用户信息类
static class UserInfo {
String salt;
String encryptedPassword;
UserInfo(String salt, String encryptedPassword) {
this.salt = salt;
this.encryptedPassword = encryptedPassword;
}
}
/**
* 用户注册
*/
public void register(String username, String password) {
// 生成盐值
String salt = generateSalt();
// 加密密码
String encryptedPassword = encryptPassword(password, salt);
// 保存用户信息
userDB.put(username, new UserInfo(salt, encryptedPassword));
System.out.println("用户 " + username + " 注册成功");
}
/**
* 用户登录验证
*/
public boolean login(String username, String password) {
UserInfo userInfo = userDB.get(username);
if (userInfo == null) {
System.out.println("用户不存在");
return false;
}
// 验证密码
String encryptedInput = encryptPassword(password, userInfo.salt);
boolean isValid = encryptedInput.equals(userInfo.encryptedPassword);
if (isValid) {
System.out.println("登录成功!");
} else {
System.out.println("密码错误");
}
return isValid;
}
/**
* 密码加密
*/
private String encryptPassword(String password, String salt) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 组合:salt + password + salt
String combined = salt + password + salt;
byte[] digest = md5.digest(combined.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 生成随机盐值
*/
private String generateSalt() {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
StringBuilder hexString = new StringBuilder();
for (byte b : salt) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
public static void main(String[] args) {
PasswordManager pm = new PasswordManager();
// 注册用户
pm.register("alice", "password123");
pm.register("bob", "securePass456");
System.out.println("\n--- 登录测试 ---");
// 正确密码登录
pm.login("alice", "password123");
// 错误密码登录
pm.login("alice", "wrongPassword");
// 查看存储信息
System.out.println("\n--- 数据库信息 ---");
System.out.println("Alice的盐值和加密密码:");
UserInfo aliceInfo = pm.userDB.get("alice");
System.out.println("盐值: " + aliceInfo.salt);
System.out.println("加密密码: " + aliceInfo.encryptedPassword);
}
}
使用Spring框架的MD5工具(可选)
// 如果使用Spring框架,可以直接使用DigestUtils
import org.springframework.util.DigestUtils;
public class SpringMD5Example {
public static void main(String[] args) {
String password = "hello123";
// 使用Spring的DigestUtils
String md5Hex = DigestUtils.md5DigestAsHex(password.getBytes());
System.out.println("Spring MD5: " + md5Hex);
// 或者使用Apache Commons Codec
// String md5Hex = DigestUtils.md5Hex(password);
}
}
重要提示
-
安全性考虑:
- MD5目前被认为不够安全,建议使用SHA-256或更强的算法
- 必须使用盐值(salt)防止彩虹表攻击
- 考虑使用bcrypt、scrypt或Argon2等专用密码哈希算法
-
性能优化:
- 避免频繁创建MessageDigest实例
- 考虑使用线程池或缓存机制
-
编码问题:
- 注意字符串编码,建议统一使用UTF-8
- 字节数组和十六进制字符串转换要正确处理
-
实际应用:
- 不要只用MD5,建议组合使用
- 考虑加盐次数和盐值长度
- 存储时同时保存盐值和加密结果
这个案例包含了从基础到实际应用的各种场景,可以根据具体需求选择合适的实现方式。