Java案例如何实现SHA加密?

wen java案例 10

本文目录导读:

Java案例如何实现SHA加密?

  1. 基础SHA加密实现
  2. 更完善的SHA工具类
  3. 使用Apache Commons Codec简化实现
  4. 加密密码的安全实践
  5. 注意事项

在Java中实现SHA加密非常简单,主要使用java.security.MessageDigest类,以下是完整的案例实现:

基础SHA加密实现

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
public class SHAEncryption {
    /**
     * SHA加密方法
     * @param input 待加密的字符串
     * @param algorithm 算法名称 (SHA-1, SHA-256, SHA-384, SHA-512)
     * @return 加密后的十六进制字符串
     */
    public static String shaEncrypt(String input, String algorithm) {
        try {
            // 获取MessageDigest实例
            MessageDigest digest = MessageDigest.getInstance(algorithm);
            // 执行加密
            byte[] hashBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8));
            // 转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("不支持的算法: " + algorithm, e);
        }
    }
    // 测试方法
    public static void main(String[] args) {
        String originalText = "Hello, World!";
        System.out.println("原始文本: " + originalText);
        System.out.println("SHA-1: " + shaEncrypt(originalText, "SHA-1"));
        System.out.println("SHA-256: " + shaEncrypt(originalText, "SHA-256"));
        System.out.println("SHA-384: " + shaEncrypt(originalText, "SHA-384"));
        System.out.println("SHA-512: " + shaEncrypt(originalText, "SHA-512"));
    }
}

更完善的SHA工具类

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
public class SHAUtils {
    // 支持的SHA算法
    public static final String SHA1 = "SHA-1";
    public static final String SHA256 = "SHA-256";
    public static final String SHA384 = "SHA-384";
    public static final String SHA512 = "SHA-512";
    /**
     * SHA-1加密
     */
    public static String sha1(String input) {
        return shaEncrypt(input, SHA1);
    }
    /**
     * SHA-256加密
     */
    public static String sha256(String input) {
        return shaEncrypt(input, SHA256);
    }
    /**
     * SHA-384加密
     */
    public static String sha384(String input) {
        return shaEncrypt(input, SHA384);
    }
    /**
     * SHA-512加密
     */
    public static String sha512(String input) {
        return shaEncrypt(input, SHA512);
    }
    /**
     * 通用的SHA加密方法
     */
    public static String shaEncrypt(String input, String algorithm) {
        if (input == null || input.isEmpty()) {
            throw new IllegalArgumentException("输入不能为空");
        }
        try {
            MessageDigest digest = MessageDigest.getInstance(algorithm);
            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("不支持的算法: " + algorithm, e);
        }
    }
    /**
     * 字节数组转十六进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }
    /**
     * 文件SHA加密
     */
    public static String shaFile(String filePath, String algorithm) throws Exception {
        MessageDigest digest = MessageDigest.getInstance(algorithm);
        try (java.io.FileInputStream fis = new java.io.FileInputStream(filePath)) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                digest.update(buffer, 0, bytesRead);
            }
        }
        byte[] hash = digest.digest();
        return bytesToHex(hash);
    }
    // 测试方法
    public static void main(String[] args) {
        try {
            String text = "这是一个测试文本";
            System.out.println("=== 字符串SHA加密 ===");
            System.out.println("原始文本: " + text);
            System.out.println("SHA-1:   " + sha1(text));
            System.out.println("SHA-256: " + sha256(text));
            System.out.println("SHA-384: " + sha384(text));
            System.out.println("SHA-512: " + sha512(text));
            // 文件SHA加密示例
            // System.out.println("\n文件SHA-256: " + shaFile("test.txt", SHA256));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用Apache Commons Codec简化实现

如果项目使用了Apache Commons Codec库,可以更简洁地实现:

import org.apache.commons.codec.digest.DigestUtils;
public class SHAWithApache {
    public static void main(String[] args) {
        String text = "Hello, World!";
        // 使用Apache Commons Codec
        String sha1Hex = DigestUtils.sha1Hex(text);
        String sha256Hex = DigestUtils.sha256Hex(text);
        String sha384Hex = DigestUtils.sha384Hex(text);
        String sha512Hex = DigestUtils.sha512Hex(text);
        System.out.println("SHA-1  : " + sha1Hex);
        System.out.println("SHA-256: " + sha256Hex);
        System.out.println("SHA-384: " + sha384Hex);
        System.out.println("SHA-512: " + sha512Hex);
    }
}

Maven依赖:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

加密密码的安全实践

实际应用中,存储密码不应直接使用简单SHA加密,建议使用加盐+多次迭代的方法:

import java.security.MessageDigest;
import java.security.SecureRandom;
import java.nio.charset.StandardCharsets;
public class SecurePasswordHasher {
    /**
     * 生成带盐值的SHA-256哈希
     */
    public static String hashPassword(String password, byte[] salt) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(salt);
            byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
            // 进行多次迭代增加安全性
            for (int i = 0; i < 1000; i++) {
                digest.reset();
                hash = digest.digest(hash);
            }
            return bytesToHex(hash);
        } catch (Exception e) {
            throw new RuntimeException("密码加密失败", e);
        }
    }
    /**
     * 生成随机盐值
     */
    public static byte[] generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16];
        random.nextBytes(salt);
        return salt;
    }
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }
    public static void main(String[] args) {
        String password = "mySecurePassword123";
        // 生成盐值
        byte[] salt = generateSalt();
        String saltHex = bytesToHex(salt);
        // 加密密码
        String hashedPassword = hashPassword(password, salt);
        System.out.println("盐值: " + saltHex);
        System.out.println("哈希密码: " + hashedPassword);
    }
}

注意事项

  1. 密码存储:不要直接使用SHA加密密码,应使用bcrypt、scrypt或Argon2等专门设计用于密码哈希的算法
  2. 算法选择:SHA-1已不安全,建议使用SHA-256或更强算法
  3. 字符编码:始终明确指定字符编码(推荐UTF-8)
  4. 异常处理:正确处理NoSuchAlgorithmException异常
  5. 性能考虑:对于大文件加密,使用缓冲区分块读取

这些示例涵盖了Java中SHA加密的基本实现和最佳实践。

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