From af774787aa80500cfd3c1beee1641d766e07512c Mon Sep 17 00:00:00 2001 From: vincent Date: Tue, 1 Sep 2026 16:45:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=B9=B3=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/ApiSignUtil.java | 62 ++++++++++++++++++- .../handler/ApiCryptoFilter.java | 2 +- .../handler/ApiDecryptRequestWrapper.java | 2 +- .../handler/ApiSignInterceptor.java | 10 +-- 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/ApiSignUtil.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/ApiSignUtil.java index 4661c6e7..e096483b 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/ApiSignUtil.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/ApiSignUtil.java @@ -1,10 +1,14 @@ -package com.zdxt.enforcementcode.common.util.api; +package com.zdxt.enforcementcode.common.util; import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.RandomUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; @@ -19,6 +23,7 @@ import java.util.stream.Collectors; public class ApiSignUtil { private static final String SIGN_ALGORITHM = "SHA256withRSA"; + private static final String HMAC_ALGORITHM = "HmacSHA256"; public static String generateRsaKeyPair() { RSA rsa = SecureUtil.rsa(); @@ -64,4 +69,59 @@ public class ApiSignUtil { RSA rsa = SecureUtil.rsa(privateKeyBase64, null); return rsa.decryptStr(data, KeyType.PrivateKey, StandardCharsets.UTF_8); } + + public static String hmacSign(String content, String appSecret) throws Exception { + Mac mac = Mac.getInstance(HMAC_ALGORITHM); + SecretKeySpec keySpec = new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), HMAC_ALGORITHM); + mac.init(keySpec); + byte[] hmacBytes = mac.doFinal(content.getBytes(StandardCharsets.UTF_8)); + return Base64.encode(hmacBytes); + } + + public static boolean hmacVerify(String content, String signBase64, String appSecret) throws Exception { + String expected = hmacSign(content, appSecret); + return expected.equals(signBase64); + } + + public static String generateAppSecret() { + return RandomUtil.randomString(32); + } + + public static void main(String[] args) { + long nowMillis = System.currentTimeMillis(); + long nowSeconds = nowMillis / 1000; + System.out.println("当前时间戳(秒): " + nowSeconds); + System.out.println("当前时间戳(毫秒): " + nowMillis); + System.out.println(); + + String appKey = RandomUtil.randomNumbers(10); + String appSecret = generateAppSecret(); + + RSA platformRsa = SecureUtil.rsa(); + String platformPublicKey = platformRsa.getPublicKeyBase64(); + String platformPrivateKey = platformRsa.getPrivateKeyBase64(); + + RSA callerRsa = SecureUtil.rsa(); + String callerPublicKey = callerRsa.getPublicKeyBase64(); + + String sql = "INSERT INTO sys_api_platform_config " + + "(channel_name, channel_no, app_key, app_secret, " + + "platform_public_key, platform_private_key, caller_public_key, " + + "sign_enabled, encrypt_enabled, status, create_time) VALUES (\n" + + " '龙岗', 'longgang', '" + appKey + "', '" + appSecret + "',\n" + + " '" + platformPublicKey + "',\n" + + " '" + platformPrivateKey + "',\n" + + " '" + callerPublicKey + "',\n" + + " 1, 0, '0', NOW()\n" + + ");"; + + System.out.println(sql); + System.out.println(); + System.out.println("=== 密钥信息(交给调用方) ==="); + System.out.println("app_key: " + appKey); + System.out.println("app_secret: " + appSecret + " (HMAC签名用)"); + System.out.println("platformPublicKey: " + platformPublicKey + " (加密请求用)"); + } + + } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiCryptoFilter.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiCryptoFilter.java index be454333..058ca0bf 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiCryptoFilter.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiCryptoFilter.java @@ -1,7 +1,7 @@ package com.zdxt.enforcementcode.handler; import cn.hutool.core.util.StrUtil; -import com.zdxt.enforcementcode.common.util.api.ApiSignUtil; +import com.zdxt.enforcementcode.common.util.ApiSignUtil; import com.zdxt.enforcementcode.config.ApiPlatformConfig; import com.zdxt.enforcementcode.domain.SysApiPlatformConfigEntity; import com.zdxt.enforcementcode.service.ISysApiPlatformConfigService; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiDecryptRequestWrapper.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiDecryptRequestWrapper.java index 78fc8126..44b95b12 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiDecryptRequestWrapper.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiDecryptRequestWrapper.java @@ -1,7 +1,7 @@ package com.zdxt.enforcementcode.handler; import cn.hutool.core.io.IoUtil; -import com.zdxt.enforcementcode.common.util.api.ApiSignUtil; +import com.zdxt.enforcementcode.common.util.ApiSignUtil; import jakarta.servlet.ReadListener; import jakarta.servlet.ServletInputStream; import jakarta.servlet.http.HttpServletRequest; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiSignInterceptor.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiSignInterceptor.java index 3b83982e..b4a46c1e 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiSignInterceptor.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/handler/ApiSignInterceptor.java @@ -1,7 +1,7 @@ package com.zdxt.enforcementcode.handler; import cn.hutool.core.util.StrUtil; -import com.zdxt.enforcementcode.common.util.api.ApiSignUtil; +import com.zdxt.enforcementcode.common.util.ApiSignUtil; import com.zdxt.enforcementcode.config.ApiPlatformConfig; import com.zdxt.enforcementcode.domain.SysApiPlatformConfigEntity; import com.zdxt.enforcementcode.service.ISysApiPlatformConfigService; @@ -91,13 +91,7 @@ public class ApiSignInterceptor implements HandlerInterceptor { String signContent = ApiSignUtil.buildSignContent(signParams); log.debug("签名原文: {}", signContent); - boolean verified = ApiSignUtil.verify(signContent, sign, consumer.getAppSecret()); - if (!verified) { - try { - verified = ApiSignUtil.verify(signContent, sign, consumer.getCallerPublicKey()); - } catch (Exception ignored) { - } - } + boolean verified = ApiSignUtil.hmacVerify(signContent, sign, consumer.getAppSecret()); if (!verified) { writeError(response, "签名验证失败");