Initial commit: PAR Server with Spring Boot 3.2, MyBatis-Plus, Flyway

This commit is contained in:
mediabot-pt
2026-06-29 10:43:24 +08:00
commit baa04b5138
60 changed files with 7043 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
package com.par.common.util;
import org.apache.commons.codec.digest.HmacUtils;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
/**
* HMAC 签名工具类
*/
public class HmacUtil {
private static final String HMAC_ALGORITHM = "HmacSHA256";
/**
* 生成 HMAC-SHA256 签名
*
* @param secret 密钥
* @param data 待签名数据
* @return Base64 编码的签名
*/
public static String sign(String secret, String data) {
byte[] signature = new HmacUtils(HMAC_ALGORITHM, secret).hmac(data);
return Base64.getEncoder().encodeToString(signature);
}
/**
* 验证签名
*
* @param secret 密钥
* @param data 待签名数据
* @param signature 待验证的签名
* @return 是否匹配
*/
public static boolean verify(String secret, String data, String signature) {
String expected = sign(secret, data);
return MessageDigest.isEqual(
signature.getBytes(StandardCharsets.UTF_8),
expected.getBytes(StandardCharsets.UTF_8)
);
}
/**
* 构建签名内容字符串
* 格式: METHOD\nPATH\nTIMESTAMP\nBODY_SHA256
*/
public static String buildSignContent(String method, String path, long timestamp, String bodySha256) {
return method.toUpperCase() + "\n" + path + "\n" + timestamp + "\n" + bodySha256;
}
/**
* 计算 SHA-256 哈希
*/
public static String sha256(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hash);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA-256 algorithm not available", e);
}
}
/**
* 生成匿名ID(邮箱SHA-256前16位)
*/
public static String generateAnonymousId(String email) {
String hash = sha256(email.toLowerCase().trim());
return hash.substring(0, 16);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}

View File

@@ -0,0 +1,25 @@
package com.par.common.util;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* 密码工具类
*/
public class PasswordUtil {
private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
/**
* 加密密码
*/
public static String encode(String rawPassword) {
return encoder.encode(rawPassword);
}
/**
* 验证密码
*/
public static boolean matches(String rawPassword, String encodedPassword) {
return encoder.matches(rawPassword, encodedPassword);
}
}