86 lines
2.8 KiB
Java
86 lines
2.8 KiB
Java
package com.cdzy.common.utils;
|
||
|
||
import java.nio.charset.StandardCharsets;
|
||
import java.security.MessageDigest;
|
||
import java.security.SecureRandom;
|
||
import java.util.Base64;
|
||
import java.util.HexFormat;
|
||
|
||
/**
|
||
* SHA-256 加盐加密工具类
|
||
*/
|
||
public class SHA256WithSaltUtil {
|
||
|
||
private static final int SALT_LENGTH = 16; // 盐值长度(16字节 = 128位)
|
||
private static final String ALGORITHM = "SHA-256";
|
||
private static final HexFormat HEX_FORMAT = HexFormat.of();
|
||
|
||
/**
|
||
* 生成随机盐值
|
||
*/
|
||
public static String generateSalt() {
|
||
SecureRandom random = new SecureRandom();
|
||
byte[] salt = new byte[SALT_LENGTH];
|
||
random.nextBytes(salt);
|
||
return Base64.getEncoder().encodeToString(salt);
|
||
}
|
||
|
||
/**
|
||
* 加密密码(SHA-256 + 盐值)
|
||
* @param password 原始密码
|
||
* @param salt 盐值(如果为null则自动生成)
|
||
* @return 返回加密后的密码和盐值组合字符串(格式:密文:盐值)
|
||
*/
|
||
public static String encrypt(String password, String salt) {
|
||
try {
|
||
// 如果未提供盐值,则生成新盐值
|
||
String usedSalt = (salt == null) ? generateSalt() : salt;
|
||
|
||
MessageDigest md = MessageDigest.getInstance(ALGORITHM);
|
||
md.update(Base64.getDecoder().decode(usedSalt)); // 加入盐值
|
||
byte[] hash = md.digest(password.getBytes(StandardCharsets.UTF_8));
|
||
|
||
// 返回格式:HEX(哈希值):Base64(盐值)
|
||
return HEX_FORMAT.formatHex(hash) + ":" + usedSalt;
|
||
} catch (Exception e) {
|
||
throw new RuntimeException("密码加密失败", e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 验证密码
|
||
* @param inputPassword 用户输入的密码
|
||
* @param storedHash 数据库存储的加密字符串(格式:密文:盐值)
|
||
* @return 是否匹配
|
||
*/
|
||
public static boolean verify(String inputPassword, String storedHash) {
|
||
if (inputPassword == null || storedHash == null) {
|
||
return false;
|
||
}
|
||
|
||
String[] parts = storedHash.split(":");
|
||
if (parts.length != 2) {
|
||
throw new IllegalArgumentException("存储的密码格式无效");
|
||
}
|
||
|
||
String inputHash = encrypt(inputPassword, parts[1]);
|
||
return inputHash.equals(storedHash);
|
||
}
|
||
|
||
// 测试示例
|
||
public static void main(String[] args) {
|
||
String password = "admin123";
|
||
|
||
// 加密
|
||
String encrypted = encrypt(password, null);
|
||
System.out.println("加密结果: " + encrypted);
|
||
|
||
// 验证
|
||
boolean matched = verify(password, encrypted);
|
||
System.out.println("验证结果: " + matched);
|
||
|
||
// 错误密码测试
|
||
boolean wrongMatch = verify("wrongPassword", encrypted);
|
||
System.out.println("错误密码测试: " + wrongMatch);
|
||
}
|
||
} |