添加 openapi 的认证头
Some checks failed
CI / build-test (push) Has been cancelled

This commit is contained in:
cheney 2026-05-28 14:56:01 +08:00
parent 1b2825c52c
commit 3646572581
5 changed files with 120 additions and 72 deletions

View File

@ -50,11 +50,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.17</version>
</dependency>
</dependencies> </dependencies>

View File

@ -1,16 +1,19 @@
package cn.com.infosec.netsign.agent; package cn.com.infosec.netsign.agent;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
public class Main public class Main
{ {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("test");
PBCAgent2G signClient = new PBCAgent2G(); 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 { 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) { } catch (Exception e) {
System.out.println("签名失败:" + e.getMessage()); System.out.println("签名失败:" + e.getMessage());

View File

@ -3,12 +3,11 @@ package cn.com.infosec.netsign.agent;
import cn.com.infosec.netsign.agent.config.OkHttpClientHolder; import cn.com.infosec.netsign.agent.config.OkHttpClientHolder;
import cn.com.infosec.netsign.agent.dto.*; import cn.com.infosec.netsign.agent.dto.*;
import cn.com.infosec.netsign.agent.exception.BusinessException; 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.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*; import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
@ -21,9 +20,13 @@ public class PBCAgent2G{
private static final MediaType JSON_MEDIA_TYPE = private static final MediaType JSON_MEDIA_TYPE =
MediaType.parse("application/json; charset=utf-8"); 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 rawSignPath = "/rawSign";
private static final String rawVerifyPath = "/rawVerify"; private static final String rawVerifyPath = "/rawVerify";
@ -41,6 +44,8 @@ public class PBCAgent2G{
private int orderdn; private int orderdn;
private int timeout; private int timeout;
private String baseUrl = "http://127.0.0.1:8088/openapi/v1/openapi";
private final ThreadLocal<Integer> lastReturnCode = new ThreadLocal<>(); private final ThreadLocal<Integer> lastReturnCode = new ThreadLocal<>();
public PBCAgent2G() { public PBCAgent2G() {
@ -53,6 +58,18 @@ public class PBCAgent2G{
this.objectMapper = new ObjectMapper(); 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){ public void isDebug(boolean isDebug){
this.isDebug = isDebug; this.isDebug = isDebug;
} }
@ -79,21 +96,23 @@ public class PBCAgent2G{
} }
public boolean openSignServer(String ip, int port, String password){ public boolean openSignServer(String ip, int port, String password){
System.out.println(ip); System.out.println("ip: " + ip);
System.out.println(port); System.out.println("port: " + port);
System.out.println(password); System.out.println("password: " + password);
baseUrl = "http://"+ ip +":" + port +"/openapi/v1/openapi";
return true; return true;
}; };
public boolean[] openSignServer(String ip, String port,String password){ public boolean[] openSignServer(String ip, String port,String password){
System.out.println(ip); System.out.println("ip: " + ip);
System.out.println(port); System.out.println("port: " + port);
System.out.println(password); System.out.println("password: " + password);
baseUrl = "http://"+ ip +":" + port +"/openapi/v1/openapi";
return new boolean[]{true}; return new boolean[]{true};
}; };
public String rawSign(byte[] origBytes, String dn) { public String rawSign(byte[] origBytes, String dn) {
logger.info("调用rawSign, dn:" + dn); System.out.println("调用rawSign, dn:" + dn);
String sessionId = UUID.randomUUID().toString().replace("-", ""); String sessionId = UUID.randomUUID().toString().replace("-", "");
if (origBytes == null) { if (origBytes == null) {
@ -131,17 +150,17 @@ public class PBCAgent2G{
JSON_MEDIA_TYPE JSON_MEDIA_TYPE
); );
Request request = new Request.Builder() Request.Builder requestBuilder = new Request.Builder()
.url(buildUrl(rawSignPath)) .url(buildUrl(rawSignPath))
.post(requestBody) .post(requestBody)
.addHeader("Content-Type", "application/json") .addHeader("Content-Type", "application/json");
.addHeader("X-API-Key", apiKey) addSignHeaders(requestBuilder);
.build(); Request request = requestBuilder.build();
logger.info("准备连接签名服务器"); System.out.println("准备连接签名服务器");
try (Response response = okHttpClient.newCall(request).execute()) { try (Response response = okHttpClient.newCall(request).execute()) {
logger.info("连接成功,并收到响应"); System.out.println("连接成功,并收到响应");
String responseBody = response.body() == null ? "" : response.body().string(); String responseBody = response.body() == null ? "" : response.body().string();
JsonNode root = objectMapper.readTree(responseBody); JsonNode root = objectMapper.readTree(responseBody);
int code = root.get("code").asInt(); int code = root.get("code").asInt();
@ -160,16 +179,16 @@ public class PBCAgent2G{
} }
} catch (IOException e) { } catch (IOException e) {
logger.info("连接签名服务器异常" + e.getMessage()); System.out.println("连接签名服务器异常" + e.getMessage());
throw new RuntimeException("调用rawSign异常:" + e.getMessage(), e); throw new RuntimeException("调用rawSign异常:" + e.getMessage(), e);
} finally { } finally {
logger.info("请求结束, 连接资源已释放"); System.out.println("请求结束, 连接资源已释放");
} }
} }
public boolean rawVerify(byte[] origBytes, String certStr, String dn) { 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("-", ""); String sessionId = UUID.randomUUID().toString().replace("-", "");
if (origBytes == null) { if (origBytes == null) {
@ -213,16 +232,16 @@ public class PBCAgent2G{
JSON_MEDIA_TYPE JSON_MEDIA_TYPE
); );
Request request = new Request.Builder() Request.Builder requestBuilder = new Request.Builder()
.url(buildUrl(rawVerifyPath)) .url(buildUrl(rawVerifyPath))
.post(requestBody) .post(requestBody)
.addHeader("Content-Type", "application/json") .addHeader("Content-Type", "application/json");
.addHeader("X-API-Key", apiKey) addSignHeaders(requestBuilder);
.build(); Request request = requestBuilder.build();
logger.info("准备连接签名服务器"); System.out.println("准备连接签名服务器");
try (Response response = okHttpClient.newCall(request).execute()) { try (Response response = okHttpClient.newCall(request).execute()) {
logger.info("连接成功,并收到响应"); System.out.println("连接成功,并收到响应");
String responseBody = response.body() == null ? "" : response.body().string(); String responseBody = response.body() == null ? "" : response.body().string();
JsonNode root = objectMapper.readTree(responseBody); JsonNode root = objectMapper.readTree(responseBody);
int code = root.get("code").asInt(); int code = root.get("code").asInt();
@ -240,16 +259,16 @@ public class PBCAgent2G{
} }
} catch (IOException e) { } catch (IOException e) {
logger.info("连接签名服务器异常" + e.getMessage()); System.out.println("连接签名服务器异常" + e.getMessage());
throw new RuntimeException("调用rawVerify异常", e); throw new RuntimeException("调用rawVerify异常", e);
} finally { } finally {
logger.info("请求结束, 连接资源已释放"); System.out.println("请求结束, 连接资源已释放");
} }
} }
public String dettachedSign(byte[] origBytes, String dn) { public String dettachedSign(byte[] origBytes, String dn) {
logger.info("调用dettachedSign, dn:" + dn); System.out.println("调用dettachedSign, dn:" + dn);
String sessionId = UUID.randomUUID().toString().replace("-", ""); String sessionId = UUID.randomUUID().toString().replace("-", "");
if (origBytes == null) { if (origBytes == null) {
@ -283,17 +302,17 @@ public class PBCAgent2G{
JSON_MEDIA_TYPE JSON_MEDIA_TYPE
); );
Request request = new Request.Builder() Request.Builder requestBuilder = new Request.Builder()
.url(buildUrl(dettachedSignPath)) .url(buildUrl(dettachedSignPath))
.post(requestBody) .post(requestBody)
.addHeader("Content-Type", "application/json") .addHeader("Content-Type", "application/json");
.addHeader("X-API-Key", apiKey) addSignHeaders(requestBuilder);
.build(); Request request = requestBuilder.build();
logger.info("准备连接签名服务器"); System.out.println("准备连接签名服务器");
try (Response response = okHttpClient.newCall(request).execute()) { try (Response response = okHttpClient.newCall(request).execute()) {
logger.info("连接成功,并收到响应"); System.out.println("连接成功,并收到响应");
String responseBody = response.body() == null ? "" : response.body().string(); String responseBody = response.body() == null ? "" : response.body().string();
JsonNode root = objectMapper.readTree(responseBody); JsonNode root = objectMapper.readTree(responseBody);
int code = root.get("code").asInt(); int code = root.get("code").asInt();
@ -311,10 +330,10 @@ public class PBCAgent2G{
} }
} catch (IOException e) { } catch (IOException e) {
logger.info("连接签名服务器异常" + e.getMessage()); System.out.println("连接签名服务器异常" + e.getMessage());
throw new RuntimeException("调用dettachedSign异常", e); throw new RuntimeException("调用dettachedSign异常", e);
} finally { } finally {
logger.info("请求结束, 连接资源已释放"); System.out.println("请求结束, 连接资源已释放");
} }
} }
@ -355,20 +374,20 @@ public class PBCAgent2G{
JSON_MEDIA_TYPE JSON_MEDIA_TYPE
); );
Request request = new Request.Builder() Request.Builder requestBuilder = new Request.Builder()
.url(buildUrl(dettachedVerifyPath)) .url(buildUrl(dettachedVerifyPath))
.post(requestBody) .post(requestBody)
.addHeader("Content-Type", "application/json") .addHeader("Content-Type", "application/json");
.addHeader("X-API-Key", apiKey) addSignHeaders(requestBuilder);
.build(); Request request = requestBuilder.build();
logger.info("准备连接签名服务器"); System.out.println("准备连接签名服务器");
try (Response response = okHttpClient.newCall(request).execute()) { try (Response response = okHttpClient.newCall(request).execute()) {
logger.info("连接成功,并收到响应"); System.out.println("连接成功,并收到响应");
String responseBody = response.body() == null ? "" : response.body().string(); String responseBody = response.body() == null ? "" : response.body().string();
JsonNode root = objectMapper.readTree(responseBody); JsonNode root = objectMapper.readTree(responseBody);
int code = root.get("code").asInt(); int code = root.get("code").asInt();
logger.info(root.toPrettyString()); System.out.println(root.toPrettyString());
if (code == 200){ if (code == 200){
DettachedVerifyResponse data = objectMapper.treeToValue(root.get("data"), DettachedVerifyResponse.class); DettachedVerifyResponse data = objectMapper.treeToValue(root.get("data"), DettachedVerifyResponse.class);
return data.getGenericCertificate(); return data.getGenericCertificate();
@ -384,10 +403,10 @@ public class PBCAgent2G{
} }
} catch (IOException e) { } catch (IOException e) {
logger.info("连接签名服务器异常" + e.getMessage()); System.out.println("连接签名服务器异常" + e.getMessage());
throw new RuntimeException("调用dettachedVerify异常", e); throw new RuntimeException("调用dettachedVerify异常", e);
} finally { } finally {
logger.info("请求结束, 连接资源已释放"); System.out.println("请求结束, 连接资源已释放");
} }
} }
@ -429,16 +448,16 @@ public class PBCAgent2G{
JSON_MEDIA_TYPE JSON_MEDIA_TYPE
); );
Request request = new Request.Builder() Request.Builder requestBuilder = new Request.Builder()
.url(buildUrl(dettachedVerifySimplePath)) .url(buildUrl(dettachedVerifySimplePath))
.post(requestBody) .post(requestBody)
.addHeader("Content-Type", "application/json") .addHeader("Content-Type", "application/json");
.addHeader("X-API-Key", apiKey) addSignHeaders(requestBuilder);
.build(); Request request = requestBuilder.build();
logger.info("准备连接签名服务器"); System.out.println("准备连接签名服务器");
try (Response response = okHttpClient.newCall(request).execute()) { try (Response response = okHttpClient.newCall(request).execute()) {
logger.info("连接成功,并收到响应"); System.out.println("连接成功,并收到响应");
String responseBody = response.body() == null ? "" : response.body().string(); String responseBody = response.body() == null ? "" : response.body().string();
JsonNode root = objectMapper.readTree(responseBody); JsonNode root = objectMapper.readTree(responseBody);
int code = root.get("code").asInt(); int code = root.get("code").asInt();
@ -456,10 +475,10 @@ public class PBCAgent2G{
} }
} catch (IOException e) { } catch (IOException e) {
logger.info("连接签名服务器异常" + e.getMessage()); System.out.println("连接签名服务器异常" + e.getMessage());
throw new RuntimeException("调用dettachedVerifySimple异常", e); throw new RuntimeException("调用dettachedVerifySimple异常", e);
} finally { } finally {
logger.info("请求结束, 连接资源已释放"); System.out.println("请求结束, 连接资源已释放");
} }
} }
@ -495,16 +514,16 @@ public class PBCAgent2G{
JSON_MEDIA_TYPE JSON_MEDIA_TYPE
); );
Request request = new Request.Builder() Request.Builder requestBuilder = new Request.Builder()
.url(buildUrl(uploadCertPath)) .url(buildUrl(uploadCertPath))
.post(requestBody) .post(requestBody)
.addHeader("Content-Type", "application/json") .addHeader("Content-Type", "application/json");
.addHeader("X-API-Key", apiKey) addSignHeaders(requestBuilder);
.build(); Request request = requestBuilder.build();
logger.info("准备连接签名服务器"); System.out.println("准备连接签名服务器");
try (Response response = okHttpClient.newCall(request).execute()) { try (Response response = okHttpClient.newCall(request).execute()) {
logger.info("连接成功,并收到响应"); System.out.println("连接成功,并收到响应");
String responseBody = response.body() == null ? "" : response.body().string(); String responseBody = response.body() == null ? "" : response.body().string();
JsonNode root = objectMapper.readTree(responseBody); JsonNode root = objectMapper.readTree(responseBody);
int code = root.get("code").asInt(); int code = root.get("code").asInt();
@ -522,10 +541,10 @@ public class PBCAgent2G{
} }
} catch (IOException e) { } catch (IOException e) {
logger.info("连接签名服务器异常" + e.getMessage()); System.out.println("连接签名服务器异常" + e.getMessage());
throw new RuntimeException("调用uploadCert异常", e); throw new RuntimeException("调用uploadCert异常", e);
} finally { } finally {
logger.info("请求结束, 连接资源已释放"); System.out.println("请求结束, 连接资源已释放");
} }
} }
@ -536,7 +555,7 @@ public class PBCAgent2G{
private String buildUrl(String path) { private String buildUrl(String path) {
String baseUrl = "http://127.0.0.1:8080/api/v1/openapi";
if (baseUrl.endsWith("/") && path.startsWith("/")) { if (baseUrl.endsWith("/") && path.startsWith("/")) {
return baseUrl.substring(0, baseUrl.length() - 1) + path; return baseUrl.substring(0, baseUrl.length() - 1) + path;

View File

@ -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();
}
}

View File

@ -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.apiKey=key
sign-server.rawSignPath=/rawSign sign-server.rawSignPath=/rawSign