From 36465725818024f0906f9951315dd0137f8aa904 Mon Sep 17 00:00:00 2001 From: cheney Date: Thu, 28 May 2026 14:56:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20openapi=20=E7=9A=84?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openapi-sdk/pom.xml | 6 +- .../cn/com/infosec/netsign/agent/Main.java | 9 +- .../com/infosec/netsign/agent/PBCAgent2G.java | 145 ++++++++++-------- .../infosec/netsign/agent/util/HmacUtil.java | 30 ++++ .../src/main/resources/sign-server.properties | 2 +- 5 files changed, 120 insertions(+), 72 deletions(-) create mode 100644 openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/util/HmacUtil.java diff --git a/openapi-sdk/pom.xml b/openapi-sdk/pom.xml index 953388f..460131b 100644 --- a/openapi-sdk/pom.xml +++ b/openapi-sdk/pom.xml @@ -50,11 +50,7 @@ - - org.slf4j - slf4j-api - 2.0.17 - + diff --git a/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/Main.java b/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/Main.java index 7daede4..ba7407d 100644 --- a/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/Main.java +++ b/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/Main.java @@ -1,16 +1,19 @@ package cn.com.infosec.netsign.agent; - import java.nio.charset.StandardCharsets; public class Main { public static void main(String[] args) { + System.out.println("test"); PBCAgent2G signClient = new PBCAgent2G(); + signClient.openSignServer("192.168.100.197", 8088, ""); + String dn = "CN=test108100455192,OU=Organizational-1,OU=TPC-S3,O=OCA21,C=CN"; + - String dn = "C=CN,ST=Beijing,L=Beijing,O=Initial Org,OU=Initial OU,CN=Initial Entity"; try { - signClient.dettachedSign("test".getBytes(StandardCharsets.UTF_8), dn); + signClient.rawSign("test".getBytes(StandardCharsets.UTF_8), dn); +// signClient.dettachedSign("test".getBytes(StandardCharsets.UTF_8), dn); } catch (Exception e) { System.out.println("签名失败:" + e.getMessage()); diff --git a/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/PBCAgent2G.java b/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/PBCAgent2G.java index 5a10b03..6823fdd 100644 --- a/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/PBCAgent2G.java +++ b/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/PBCAgent2G.java @@ -3,12 +3,11 @@ package cn.com.infosec.netsign.agent; import cn.com.infosec.netsign.agent.config.OkHttpClientHolder; import cn.com.infosec.netsign.agent.dto.*; import cn.com.infosec.netsign.agent.exception.BusinessException; +import cn.com.infosec.netsign.agent.util.HmacUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; import java.security.cert.X509Certificate; @@ -21,9 +20,13 @@ public class PBCAgent2G{ private static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8"); - private static final Logger logger = LoggerFactory.getLogger(PBCAgent2G.class); + private static final String APP_ID_HEADER = "X-App-Id"; + private static final String TIMESTAMP_HEADER = "X-Timestamp"; + private static final String NONCE_HEADER = "X-Nonce"; + private static final String SIGNATURE_HEADER = "X-Signature"; - private static final String apiKey = "key"; + private static final String appId = "openapi-client"; + private static final String appSecret = "openapi-secret"; private static final String rawSignPath = "/rawSign"; private static final String rawVerifyPath = "/rawVerify"; @@ -41,6 +44,8 @@ public class PBCAgent2G{ private int orderdn; private int timeout; + private String baseUrl = "http://127.0.0.1:8088/openapi/v1/openapi"; + private final ThreadLocal lastReturnCode = new ThreadLocal<>(); public PBCAgent2G() { @@ -53,6 +58,18 @@ public class PBCAgent2G{ this.objectMapper = new ObjectMapper(); } + private void addSignHeaders(Request.Builder builder) { + String timestamp = String.valueOf(System.currentTimeMillis() / 1000); + String nonce = UUID.randomUUID().toString().replace("-", ""); + String content = appId + "\n" + timestamp + "\n" + nonce; + String signature = HmacUtil.hmacSha256Hex(appSecret, content); + + builder.addHeader(APP_ID_HEADER, appId); + builder.addHeader(TIMESTAMP_HEADER, timestamp); + builder.addHeader(NONCE_HEADER, nonce); + builder.addHeader(SIGNATURE_HEADER, signature); + } + public void isDebug(boolean isDebug){ this.isDebug = isDebug; } @@ -79,21 +96,23 @@ public class PBCAgent2G{ } public boolean openSignServer(String ip, int port, String password){ - System.out.println(ip); - System.out.println(port); - System.out.println(password); + System.out.println("ip: " + ip); + System.out.println("port: " + port); + System.out.println("password: " + password); + baseUrl = "http://"+ ip +":" + port +"/openapi/v1/openapi"; return true; }; public boolean[] openSignServer(String ip, String port,String password){ - System.out.println(ip); - System.out.println(port); - System.out.println(password); + System.out.println("ip: " + ip); + System.out.println("port: " + port); + System.out.println("password: " + password); + baseUrl = "http://"+ ip +":" + port +"/openapi/v1/openapi"; return new boolean[]{true}; }; public String rawSign(byte[] origBytes, String dn) { - logger.info("调用rawSign, dn:" + dn); + System.out.println("调用rawSign, dn:" + dn); String sessionId = UUID.randomUUID().toString().replace("-", ""); if (origBytes == null) { @@ -131,17 +150,17 @@ public class PBCAgent2G{ JSON_MEDIA_TYPE ); - Request request = new Request.Builder() + Request.Builder requestBuilder = new Request.Builder() .url(buildUrl(rawSignPath)) .post(requestBody) - .addHeader("Content-Type", "application/json") - .addHeader("X-API-Key", apiKey) - .build(); + .addHeader("Content-Type", "application/json"); + addSignHeaders(requestBuilder); + Request request = requestBuilder.build(); - logger.info("准备连接签名服务器"); + System.out.println("准备连接签名服务器"); try (Response response = okHttpClient.newCall(request).execute()) { - logger.info("连接成功,并收到响应"); + System.out.println("连接成功,并收到响应"); String responseBody = response.body() == null ? "" : response.body().string(); JsonNode root = objectMapper.readTree(responseBody); int code = root.get("code").asInt(); @@ -160,16 +179,16 @@ public class PBCAgent2G{ } } catch (IOException e) { - logger.info("连接签名服务器异常" + e.getMessage()); + System.out.println("连接签名服务器异常" + e.getMessage()); throw new RuntimeException("调用rawSign异常:" + e.getMessage(), e); } finally { - logger.info("请求结束, 连接资源已释放"); + System.out.println("请求结束, 连接资源已释放"); } } public boolean rawVerify(byte[] origBytes, String certStr, String dn) { - logger.info("调用rawVerify, dn:" + dn + " , certStr:" + certStr); + System.out.println("调用rawVerify, dn:" + dn + " , certStr:" + certStr); String sessionId = UUID.randomUUID().toString().replace("-", ""); if (origBytes == null) { @@ -213,16 +232,16 @@ public class PBCAgent2G{ JSON_MEDIA_TYPE ); - Request request = new Request.Builder() + Request.Builder requestBuilder = new Request.Builder() .url(buildUrl(rawVerifyPath)) .post(requestBody) - .addHeader("Content-Type", "application/json") - .addHeader("X-API-Key", apiKey) - .build(); + .addHeader("Content-Type", "application/json"); + addSignHeaders(requestBuilder); + Request request = requestBuilder.build(); - logger.info("准备连接签名服务器"); + System.out.println("准备连接签名服务器"); try (Response response = okHttpClient.newCall(request).execute()) { - logger.info("连接成功,并收到响应"); + System.out.println("连接成功,并收到响应"); String responseBody = response.body() == null ? "" : response.body().string(); JsonNode root = objectMapper.readTree(responseBody); int code = root.get("code").asInt(); @@ -240,16 +259,16 @@ public class PBCAgent2G{ } } catch (IOException e) { - logger.info("连接签名服务器异常" + e.getMessage()); + System.out.println("连接签名服务器异常" + e.getMessage()); throw new RuntimeException("调用rawVerify异常", e); } finally { - logger.info("请求结束, 连接资源已释放"); + System.out.println("请求结束, 连接资源已释放"); } } public String dettachedSign(byte[] origBytes, String dn) { - logger.info("调用dettachedSign, dn:" + dn); + System.out.println("调用dettachedSign, dn:" + dn); String sessionId = UUID.randomUUID().toString().replace("-", ""); if (origBytes == null) { @@ -283,17 +302,17 @@ public class PBCAgent2G{ JSON_MEDIA_TYPE ); - Request request = new Request.Builder() + Request.Builder requestBuilder = new Request.Builder() .url(buildUrl(dettachedSignPath)) .post(requestBody) - .addHeader("Content-Type", "application/json") - .addHeader("X-API-Key", apiKey) - .build(); + .addHeader("Content-Type", "application/json"); + addSignHeaders(requestBuilder); + Request request = requestBuilder.build(); - logger.info("准备连接签名服务器"); + System.out.println("准备连接签名服务器"); try (Response response = okHttpClient.newCall(request).execute()) { - logger.info("连接成功,并收到响应"); + System.out.println("连接成功,并收到响应"); String responseBody = response.body() == null ? "" : response.body().string(); JsonNode root = objectMapper.readTree(responseBody); int code = root.get("code").asInt(); @@ -311,10 +330,10 @@ public class PBCAgent2G{ } } catch (IOException e) { - logger.info("连接签名服务器异常" + e.getMessage()); + System.out.println("连接签名服务器异常" + e.getMessage()); throw new RuntimeException("调用dettachedSign异常", e); } finally { - logger.info("请求结束, 连接资源已释放"); + System.out.println("请求结束, 连接资源已释放"); } } @@ -355,20 +374,20 @@ public class PBCAgent2G{ JSON_MEDIA_TYPE ); - Request request = new Request.Builder() + Request.Builder requestBuilder = new Request.Builder() .url(buildUrl(dettachedVerifyPath)) .post(requestBody) - .addHeader("Content-Type", "application/json") - .addHeader("X-API-Key", apiKey) - .build(); + .addHeader("Content-Type", "application/json"); + addSignHeaders(requestBuilder); + Request request = requestBuilder.build(); - logger.info("准备连接签名服务器"); + System.out.println("准备连接签名服务器"); try (Response response = okHttpClient.newCall(request).execute()) { - logger.info("连接成功,并收到响应"); + System.out.println("连接成功,并收到响应"); String responseBody = response.body() == null ? "" : response.body().string(); JsonNode root = objectMapper.readTree(responseBody); int code = root.get("code").asInt(); - logger.info(root.toPrettyString()); + System.out.println(root.toPrettyString()); if (code == 200){ DettachedVerifyResponse data = objectMapper.treeToValue(root.get("data"), DettachedVerifyResponse.class); return data.getGenericCertificate(); @@ -384,10 +403,10 @@ public class PBCAgent2G{ } } catch (IOException e) { - logger.info("连接签名服务器异常" + e.getMessage()); + System.out.println("连接签名服务器异常" + e.getMessage()); throw new RuntimeException("调用dettachedVerify异常", e); } finally { - logger.info("请求结束, 连接资源已释放"); + System.out.println("请求结束, 连接资源已释放"); } } @@ -429,16 +448,16 @@ public class PBCAgent2G{ JSON_MEDIA_TYPE ); - Request request = new Request.Builder() + Request.Builder requestBuilder = new Request.Builder() .url(buildUrl(dettachedVerifySimplePath)) .post(requestBody) - .addHeader("Content-Type", "application/json") - .addHeader("X-API-Key", apiKey) - .build(); + .addHeader("Content-Type", "application/json"); + addSignHeaders(requestBuilder); + Request request = requestBuilder.build(); - logger.info("准备连接签名服务器"); + System.out.println("准备连接签名服务器"); try (Response response = okHttpClient.newCall(request).execute()) { - logger.info("连接成功,并收到响应"); + System.out.println("连接成功,并收到响应"); String responseBody = response.body() == null ? "" : response.body().string(); JsonNode root = objectMapper.readTree(responseBody); int code = root.get("code").asInt(); @@ -456,10 +475,10 @@ public class PBCAgent2G{ } } catch (IOException e) { - logger.info("连接签名服务器异常" + e.getMessage()); + System.out.println("连接签名服务器异常" + e.getMessage()); throw new RuntimeException("调用dettachedVerifySimple异常", e); } finally { - logger.info("请求结束, 连接资源已释放"); + System.out.println("请求结束, 连接资源已释放"); } } @@ -495,16 +514,16 @@ public class PBCAgent2G{ JSON_MEDIA_TYPE ); - Request request = new Request.Builder() + Request.Builder requestBuilder = new Request.Builder() .url(buildUrl(uploadCertPath)) .post(requestBody) - .addHeader("Content-Type", "application/json") - .addHeader("X-API-Key", apiKey) - .build(); + .addHeader("Content-Type", "application/json"); + addSignHeaders(requestBuilder); + Request request = requestBuilder.build(); - logger.info("准备连接签名服务器"); + System.out.println("准备连接签名服务器"); try (Response response = okHttpClient.newCall(request).execute()) { - logger.info("连接成功,并收到响应"); + System.out.println("连接成功,并收到响应"); String responseBody = response.body() == null ? "" : response.body().string(); JsonNode root = objectMapper.readTree(responseBody); int code = root.get("code").asInt(); @@ -522,10 +541,10 @@ public class PBCAgent2G{ } } catch (IOException e) { - logger.info("连接签名服务器异常" + e.getMessage()); + System.out.println("连接签名服务器异常" + e.getMessage()); throw new RuntimeException("调用uploadCert异常", e); } finally { - logger.info("请求结束, 连接资源已释放"); + System.out.println("请求结束, 连接资源已释放"); } } @@ -536,7 +555,7 @@ public class PBCAgent2G{ private String buildUrl(String path) { - String baseUrl = "http://127.0.0.1:8080/api/v1/openapi"; + if (baseUrl.endsWith("/") && path.startsWith("/")) { return baseUrl.substring(0, baseUrl.length() - 1) + path; diff --git a/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/util/HmacUtil.java b/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/util/HmacUtil.java new file mode 100644 index 0000000..578582e --- /dev/null +++ b/openapi-sdk/src/main/java/cn/com/infosec/netsign/agent/util/HmacUtil.java @@ -0,0 +1,30 @@ +package cn.com.infosec.netsign.agent.util; + +import java.nio.charset.StandardCharsets; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +public final class HmacUtil { + + private HmacUtil() { + } + + public static String hmacSha256Hex(String key, String content) { + try { + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + byte[] digest = mac.doFinal(content.getBytes(StandardCharsets.UTF_8)); + return toHex(digest); + } catch (Exception ex) { + throw new IllegalStateException("HMAC计算失败", ex); + } + } + + private static String toHex(byte[] bytes) { + StringBuilder builder = new StringBuilder(bytes.length * 2); + for (byte b : bytes) { + builder.append(String.format("%02x", b)); + } + return builder.toString(); + } +} \ No newline at end of file diff --git a/openapi-sdk/src/main/resources/sign-server.properties b/openapi-sdk/src/main/resources/sign-server.properties index 60c10bb..918c1fa 100644 --- a/openapi-sdk/src/main/resources/sign-server.properties +++ b/openapi-sdk/src/main/resources/sign-server.properties @@ -1,4 +1,4 @@ -sign-server.baseUrl=http://127.0.0.1:8080/api/v1/openapi +sign-server.baseUrl=http://192.168.100.197:8088/api/v1/openapi sign-server.apiKey=key sign-server.rawSignPath=/rawSign