RSASignatureUtil.java 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package com.malk.lianan;
  2. import cn.hutool.core.codec.Base64;
  3. import cn.hutool.core.exceptions.ExceptionUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import cn.hutool.crypto.SecureUtil;
  6. import cn.hutool.crypto.asymmetric.Sign;
  7. import cn.hutool.crypto.asymmetric.SignAlgorithm;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import java.nio.charset.StandardCharsets;
  11. /**
  12. * RSA签名工具类(基于Hutool)
  13. * 支持异常处理、日志记录、参数校验
  14. */
  15. public class RSASignatureUtil {
  16. private static final Logger logger = LoggerFactory.getLogger(RSASignatureUtil.class);
  17. // 默认使用SHA256withRSA
  18. private static final SignAlgorithm DEFAULT_ALGORITHM = SignAlgorithm.SHA256withRSA;
  19. /**
  20. * 生成签名(带完整错误处理)
  21. */
  22. public static String signSafe(String data, String privateKeyBase64) {
  23. return signSafe(data, privateKeyBase64, DEFAULT_ALGORITHM);
  24. }
  25. public static String signSafe(String data, String privateKeyBase64, SignAlgorithm algorithm) {
  26. // 参数校验
  27. if (StrUtil.isBlank(data)) {
  28. logger.warn("签名数据为空");
  29. return null;
  30. }
  31. if (StrUtil.isBlank(privateKeyBase64)) {
  32. logger.error("私钥为空");
  33. return null;
  34. }
  35. try {
  36. // 使用Hutool的签名工具
  37. Sign sign = SecureUtil.sign(algorithm, privateKeyBase64, null);
  38. String signature = sign.signHex(data, StandardCharsets.UTF_8);
  39. logger.debug("签名成功,数据长度: {}, 签名长度: {}",
  40. data.length(), signature.length());
  41. return signature;
  42. } catch (Exception e) {
  43. logger.error("签名失败 - 数据: {}, 算法: {}, 错误: {}",
  44. StrUtil.subPre(data, 100), // 只记录前100字符
  45. algorithm.getValue(),
  46. ExceptionUtil.getMessage(e));
  47. return null;
  48. }
  49. }
  50. /**
  51. * 验证签名(带完整错误处理)
  52. */
  53. public static boolean verifySafe(String data, String signatureBase64, String publicKeyBase64) {
  54. return verifySafe(data, signatureBase64, publicKeyBase64, DEFAULT_ALGORITHM);
  55. }
  56. public static boolean verifySafe(String data, String signatureBase64,
  57. String publicKeyBase64, SignAlgorithm algorithm) {
  58. // 参数校验
  59. if (StrUtil.isBlank(data)) {
  60. logger.warn("验证数据为空");
  61. return false;
  62. }
  63. if (StrUtil.isBlank(signatureBase64)) {
  64. logger.warn("签名为空");
  65. return false;
  66. }
  67. if (StrUtil.isBlank(publicKeyBase64)) {
  68. logger.error("公钥为空");
  69. return false;
  70. }
  71. try {
  72. // 使用Hutool的签名工具
  73. Sign sign = SecureUtil.sign(algorithm, null, publicKeyBase64);
  74. boolean isValid = sign.verify(
  75. data.getBytes(StandardCharsets.UTF_8),
  76. Base64.decode(signatureBase64)
  77. );
  78. logger.debug("签名验证结果: {}", isValid ? "通过" : "失败");
  79. return isValid;
  80. } catch (Exception e) {
  81. logger.error("签名验证失败 - 数据长度: {}, 算法: {}, 错误: {}",
  82. data.length(),
  83. algorithm.getValue(),
  84. ExceptionUtil.getMessage(e));
  85. return false;
  86. }
  87. }
  88. /**
  89. * 批量验证签名
  90. */
  91. public static boolean verifyBatch(String[] dataArray, String[] signatureArray,
  92. String publicKeyBase64) {
  93. if (dataArray == null || signatureArray == null ||
  94. dataArray.length != signatureArray.length) {
  95. logger.error("批量验证参数无效");
  96. return false;
  97. }
  98. for (int i = 0; i < dataArray.length; i++) {
  99. if (!verifySafe(dataArray[i], signatureArray[i], publicKeyBase64)) {
  100. logger.error("第 {} 个签名验证失败", i + 1);
  101. return false;
  102. }
  103. }
  104. logger.info("批量签名验证成功,共验证 {} 个签名", dataArray.length);
  105. return true;
  106. }
  107. }