Java MD5加密案例如何实操

wen java案例 21

本文目录导读:

Java MD5加密案例如何实操

  1. 基础MD5加密实现
  2. 带盐值的MD5加密
  3. 多次MD5加密(增强安全性)
  4. 文件MD5校验
  5. 实际应用示例(用户密码管理)
  6. 使用Spring框架的MD5工具(可选)
  7. 重要提示

我来详细介绍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);
    }
}

重要提示

  1. 安全性考虑

    • MD5目前被认为不够安全,建议使用SHA-256或更强的算法
    • 必须使用盐值(salt)防止彩虹表攻击
    • 考虑使用bcrypt、scrypt或Argon2等专用密码哈希算法
  2. 性能优化

    • 避免频繁创建MessageDigest实例
    • 考虑使用线程池或缓存机制
  3. 编码问题

    • 注意字符串编码,建议统一使用UTF-8
    • 字节数组和十六进制字符串转换要正确处理
  4. 实际应用

    • 不要只用MD5,建议组合使用
    • 考虑加盐次数和盐值长度
    • 存储时同时保存盐值和加密结果

这个案例包含了从基础到实际应用的各种场景,可以根据具体需求选择合适的实现方式。

抱歉,评论功能暂时关闭!