package com.malk.lianan; import cn.hutool.core.codec.Base64; import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.Sign; import cn.hutool.crypto.asymmetric.SignAlgorithm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.charset.StandardCharsets; /** * RSA签名工具类(基于Hutool) * 支持异常处理、日志记录、参数校验 */ public class RSASignatureUtil { private static final Logger logger = LoggerFactory.getLogger(RSASignatureUtil.class); // 默认使用SHA256withRSA private static final SignAlgorithm DEFAULT_ALGORITHM = SignAlgorithm.SHA256withRSA; /** * 生成签名(带完整错误处理) */ public static String signSafe(String data, String privateKeyBase64) { return signSafe(data, privateKeyBase64, DEFAULT_ALGORITHM); } public static String signSafe(String data, String privateKeyBase64, SignAlgorithm algorithm) { // 参数校验 if (StrUtil.isBlank(data)) { logger.warn("签名数据为空"); return null; } if (StrUtil.isBlank(privateKeyBase64)) { logger.error("私钥为空"); return null; } try { // 使用Hutool的签名工具 Sign sign = SecureUtil.sign(algorithm, privateKeyBase64, null); String signature = sign.signHex(data, StandardCharsets.UTF_8); logger.debug("签名成功,数据长度: {}, 签名长度: {}", data.length(), signature.length()); return signature; } catch (Exception e) { logger.error("签名失败 - 数据: {}, 算法: {}, 错误: {}", StrUtil.subPre(data, 100), // 只记录前100字符 algorithm.getValue(), ExceptionUtil.getMessage(e)); return null; } } /** * 验证签名(带完整错误处理) */ public static boolean verifySafe(String data, String signatureBase64, String publicKeyBase64) { return verifySafe(data, signatureBase64, publicKeyBase64, DEFAULT_ALGORITHM); } public static boolean verifySafe(String data, String signatureBase64, String publicKeyBase64, SignAlgorithm algorithm) { // 参数校验 if (StrUtil.isBlank(data)) { logger.warn("验证数据为空"); return false; } if (StrUtil.isBlank(signatureBase64)) { logger.warn("签名为空"); return false; } if (StrUtil.isBlank(publicKeyBase64)) { logger.error("公钥为空"); return false; } try { // 使用Hutool的签名工具 Sign sign = SecureUtil.sign(algorithm, null, publicKeyBase64); boolean isValid = sign.verify( data.getBytes(StandardCharsets.UTF_8), Base64.decode(signatureBase64) ); logger.debug("签名验证结果: {}", isValid ? "通过" : "失败"); return isValid; } catch (Exception e) { logger.error("签名验证失败 - 数据长度: {}, 算法: {}, 错误: {}", data.length(), algorithm.getValue(), ExceptionUtil.getMessage(e)); return false; } } /** * 批量验证签名 */ public static boolean verifyBatch(String[] dataArray, String[] signatureArray, String publicKeyBase64) { if (dataArray == null || signatureArray == null || dataArray.length != signatureArray.length) { logger.error("批量验证参数无效"); return false; } for (int i = 0; i < dataArray.length; i++) { if (!verifySafe(dataArray[i], signatureArray[i], publicKeyBase64)) { logger.error("第 {} 个签名验证失败", i + 1); return false; } } logger.info("批量签名验证成功,共验证 {} 个签名", dataArray.length); return true; } }