From 8f997d2a00de31715e04ef382f7aa4f1c77546b8 Mon Sep 17 00:00:00 2001 From: liulu Date: Fri, 13 Dec 2024 14:32:58 +0800 Subject: [PATCH] sdf api --- chsm-common/pom.xml | 5 ++ .../com/sunyard/chsm/config/IpFilter.java | 4 +- .../chsm/sdf/adapter/BcSdfApiAdaptor.java | 74 ++++++++++++++----- .../chsm/sdf/adapter/RpcSdfAdapter.java | 0 .../sdf/adapter/SdfApiAdapterFactory.java | 38 +++++++++- .../sdf/adapter/SunyardJnaSdfAdaptor.java | 72 +++++------------- .../chsm/sdf/lib/SunyardSdfLibrary.java | 2 + .../sunyard/chsm/sdf/model/EccSignature.java | 22 +++++- .../com/sunyard/chsm/service/TmkService.java | 25 +++++-- .../sunyard/chsm/sdf/SingleSdfApiService.java | 27 +++---- .../com/sunyard/chsm/task/DeviceTask.java | 15 ++-- .../src/main/resources/application.yml | 1 - ...SdfApiTest.java => SdfApiAdapterTest.java} | 71 ++++++++++++------ pom.xml | 6 -- 14 files changed, 230 insertions(+), 132 deletions(-) rename {chsm-web-server/src/test => chsm-common/src/main}/java/com/sunyard/chsm/sdf/adapter/RpcSdfAdapter.java (100%) rename chsm-web-server/src/test/java/com/sunyard/chsm/sdf/{SdfApiTest.java => SdfApiAdapterTest.java} (70%) diff --git a/chsm-common/pom.xml b/chsm-common/pom.xml index dfc4c1d..62d71f0 100644 --- a/chsm-common/pom.xml +++ b/chsm-common/pom.xml @@ -57,6 +57,11 @@ net.java.dev.jna jna + + com.github.briandilley.jsonrpc4j + jsonrpc4j + 1.6 + diff --git a/chsm-common/src/main/java/com/sunyard/chsm/config/IpFilter.java b/chsm-common/src/main/java/com/sunyard/chsm/config/IpFilter.java index 76a52e2..b4d661d 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/config/IpFilter.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/config/IpFilter.java @@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.web.filter.OncePerRequestFilter; @@ -34,6 +35,7 @@ import java.util.stream.Collectors; * @since 2024/12/2 */ @Slf4j +@Component public class IpFilter extends OncePerRequestFilter implements ApplicationRunner { public static List whiteIps = new ArrayList<>(); @@ -75,7 +77,7 @@ public class IpFilter extends OncePerRequestFilter implements ApplicationRunner if (enableWhiteIp) { syncWhiteIps(); } - }, 0L, 5L, TimeUnit.MINUTES); + }, 1L, 5L, TimeUnit.MINUTES); } diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java index af7c42b..80877a2 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java @@ -12,13 +12,11 @@ import com.sunyard.chsm.utils.gm.BCECUtils; import com.sunyard.chsm.utils.gm.BCSM2Utils; import com.sunyard.chsm.utils.gm.BCSM4Utils; import lombok.SneakyThrows; -import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.digests.SM3Digest; +import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.signers.SM2Signer; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.math.ec.ECPoint; @@ -29,6 +27,7 @@ import java.math.BigInteger; import java.security.KeyPair; import java.security.SecureRandom; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -135,28 +134,69 @@ public class BcSdfApiAdaptor implements SdfApiAdapter { } } + private static final SecureRandom RANDOM = new SecureRandom(); + @Override public EccSignature externalSignECC(String sessionHandle, EccPriKey privateKey, byte[] pucData) { ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(privateKey.getD()); - try { - SM2Signer signer = new SM2Signer(new NullDigest()); - signer.init(true, pri); - signer.update(pucData, 0, pucData.length); - byte[] signature = signer.generateSignature(); - return EccSignature.fromBytes(signature); - } catch (CryptoException e) { - throw new IllegalArgumentException(e); - } + + BigInteger n = pri.getParameters().getN(); + BigInteger d = pri.getD(); + + BigInteger e = new BigInteger(1, pucData); + BigInteger r, s = null; + + do { + BigInteger k; + do { + k = new BigInteger(n.bitLength(), RANDOM); + } while (k.compareTo(BigInteger.ONE) < 0 || k.compareTo(n) >= 0); + + ECPoint kG = pri.getParameters().getG().multiply(k).normalize(); + BigInteger x1 = kG.getAffineXCoord().toBigInteger(); + + r = e.add(x1).mod(n); + + if (r.equals(BigInteger.ZERO) || r.add(k).equals(n)) { + continue; + } + + BigInteger dPlus1Inv = d.add(BigInteger.ONE).modInverse(n); + s = dPlus1Inv.multiply(k.subtract(r.multiply(d))).mod(n); + + } while (Objects.equals(s, BigInteger.ZERO)); + return new EccSignature(BigIntegers.asUnsignedByteArray(32, r), + BigIntegers.asUnsignedByteArray(32, s)); } @Override public boolean externalVerifyECC(String sessionHandle, EccPubKey publicKey, byte[] pucData, EccSignature pucSignature) { ECPublicKeyParameters pub = BCECUtils.createECPublicKeyParameters(publicKey.getX(), publicKey.getY()); - SM2Signer verifier = new SM2Signer(new NullDigest()); - verifier.init(false, pub); - // 验证数据 - verifier.update(pucData, 0, pucData.length); - return verifier.verifySignature(pucSignature.getRawSignBytes()); + if (pucData.length != 32) { + throw new IllegalArgumentException("Hash length must be 32 bytes"); + } + ECDomainParameters domainParams = pub.getParameters(); + ECPoint G = domainParams.getG(); + BigInteger n = domainParams.getN(); + ECPoint Q = pub.getQ(); + BigInteger e = new BigInteger(1, pucData); + + BigInteger r = new BigInteger(1, pucSignature.getR()); + BigInteger s = new BigInteger(1, pucSignature.getS()); + if (r.compareTo(BigIntegers.ONE) < 0 || r.compareTo(n) >= 0 || s.compareTo(BigIntegers.ONE) < 0 || s.compareTo(n) >= 0) { + return false; + } + + BigInteger t = r.add(s).mod(n); + if (t.equals(BigInteger.ZERO)) { + return false; + } + + ECPoint point = G.multiply(s).add(Q.multiply(t)).normalize(); + + BigInteger R = e.add(point.getAffineXCoord().toBigInteger()).mod(n); + + return R.equals(r); } @Override diff --git a/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/adapter/RpcSdfAdapter.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/RpcSdfAdapter.java similarity index 100% rename from chsm-web-server/src/test/java/com/sunyard/chsm/sdf/adapter/RpcSdfAdapter.java rename to chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/RpcSdfAdapter.java diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SdfApiAdapterFactory.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SdfApiAdapterFactory.java index f95097d..78a9fd0 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SdfApiAdapterFactory.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SdfApiAdapterFactory.java @@ -1,15 +1,26 @@ package com.sunyard.chsm.sdf.adapter; +import com.googlecode.jsonrpc4j.JsonRpcHttpClient; +import com.googlecode.jsonrpc4j.ProxyUtil; +import com.sun.jna.Platform; import com.sunyard.chsm.enums.ManufacturerModelEnum; +import com.sunyard.chsm.utils.JsonUtils; +import lombok.extern.slf4j.Slf4j; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; +import java.lang.reflect.Proxy; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; import java.util.Objects; /** * @author liulu * @since 2024/11/5 */ +@Slf4j public class SdfApiAdapterFactory { @@ -28,11 +39,36 @@ public class SdfApiAdapterFactory { } switch (modelEnum) { case enc001: - return new SunyardJnaSdfAdaptor(ip, port); + return Platform.isMac() ? getProxyRcpAdapter(ip, port) : new SunyardJnaSdfAdaptor(ip, port); default: throw new UnsupportedOperationException("不支持的设备型号: " + model); } } + private static final RpcSdfAdapter rpcSdfAdapter; + + static { + try { + JsonRpcHttpClient client = new JsonRpcHttpClient(JsonUtils.objectMapper(), + new URL("http://172.16.18.46:9989/sdf/adapter"), Collections.emptyMap()); + rpcSdfAdapter = ProxyUtil.createClientProxy( + ClassUtils.getDefaultClassLoader(), RpcSdfAdapter.class, client); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + public static SdfApiAdapter getProxyRcpAdapter(String ip, Integer port) { + return (SdfApiAdapter) Proxy.newProxyInstance(ClassUtils.getDefaultClassLoader(), + new Class[]{SdfApiAdapter.class}, + (proxy, method, args) -> { + if (Objects.equals(method.getName(), "openDevice")) { + return rpcSdfAdapter.openDevice(ip, port, 3000, 3000, 0); + } + return method.invoke(rpcSdfAdapter, args); + } + ); + } + } diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SunyardJnaSdfAdaptor.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SunyardJnaSdfAdaptor.java index 266494f..91e291a 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SunyardJnaSdfAdaptor.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SunyardJnaSdfAdaptor.java @@ -1,22 +1,17 @@ package com.sunyard.chsm.sdf.adapter; -import com.sun.jna.Native; import com.sun.jna.ptr.PointerByReference; import com.sunyard.chsm.sdf.context.AlgId; import com.sunyard.chsm.sdf.context.SdrCode; import com.sunyard.chsm.sdf.context.SunyardAlgId; import com.sunyard.chsm.sdf.lib.SdfLibrary; import com.sunyard.chsm.sdf.lib.SunyardSdfLibrary; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.util.ClassUtils; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.Map; +import java.util.Objects; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; /** * @author liulu @@ -25,64 +20,48 @@ import java.util.concurrent.ConcurrentHashMap; @Slf4j public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor { - private static final Map SDF_LIB_MAP = new ConcurrentHashMap<>(); - - private final String ip; private final Integer port; - private String libName; private final Integer connTimeout; private final Integer dealTimeout; - public SunyardJnaSdfAdaptor(String ip) { - this(ip, 8889, "sdf"); - } - public SunyardJnaSdfAdaptor(String ip, int port) { - this(ip, port, "sdf"); + this(ip, port, 3000, 3000); } - public SunyardJnaSdfAdaptor(String ip, int port, String libName) { - this(ip, port, libName, 3000, 3000); - } - - public SunyardJnaSdfAdaptor(String ip, int port, String libName, int connTimeout, int dealTimeout) { + public SunyardJnaSdfAdaptor(String ip, int port, int connTimeout, int dealTimeout) { super((SdfLibrary) Proxy.newProxyInstance(ClassUtils.getDefaultClassLoader(), new Class[]{SdfLibrary.class}, - new InvocationHandler() { - private final SunyardSdfLibrary sunyardSdfLibrary; - - { - sunyardSdfLibrary = SDF_LIB_MAP.computeIfAbsent(libName, k -> Native.load(libName, SunyardSdfLibrary.class)); - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - Object res = method.invoke(sunyardSdfLibrary, args); - if (method.getName().startsWith("SDF_") && res instanceof Integer) { - int resInt = (Integer) res; - if (resInt != SdrCode.SDR_OK.getCode()) { - log.warn("调用异常: {}, 返回值: {} -{}", method.getName(), Integer.toHexString(resInt), resInt); - SdrCode sdrCode = SdrCode.of((Integer) res); - throw new IllegalArgumentException(sdrCode != null ? sdrCode.getMsg() : "调用sdf接口异常: " + Integer.toHexString(resInt)); - } - } + (proxy, method, args) -> { + Object res = method.invoke(SunyardSdfLibrary.INSTANCE, args); + if (!(res instanceof Integer)) { return res; } + int resInt = (Integer) res; + if (Objects.equals("SDF_ExternalVerify_ECC", method.getName())) { + log.info("SDF_ExternalVerify_ECC: {}, 返回值: {}", method.getName(), Integer.toHexString(resInt)); + return resInt; + } + if (method.getName().startsWith("SDF_")) { + if (resInt != SdrCode.SDR_OK.getCode()) { + log.warn("调用异常: {}, 返回值: {} -{}", method.getName(), Integer.toHexString(resInt), resInt); + SdrCode sdrCode = SdrCode.of((Integer) res); + throw new IllegalArgumentException(sdrCode != null ? sdrCode.getMsg() : "调用sdf接口异常: " + Integer.toHexString(resInt)); + } + } + return res; } )); this.ip = ip; this.port = port; - this.libName = libName; this.connTimeout = connTimeout; this.dealTimeout = dealTimeout; } @Override public String openDevice() { - SunyardSdfLibrary sunyardSdfLibrary = SDF_LIB_MAP.computeIfAbsent(libName, k -> Native.load(libName, SunyardSdfLibrary.class)); PointerByReference phDeviceHandle = new PointerByReference(); - sunyardSdfLibrary.SDF_OpenDevice(phDeviceHandle, safeStringBytes(ip), port, connTimeout, dealTimeout, 0); + SunyardSdfLibrary.INSTANCE.SDF_OpenDevice(phDeviceHandle, safeStringBytes(ip), port, connTimeout, dealTimeout, 0); String key = UUID.randomUUID().toString(); DEVICE_HANDLE_CONTEXT.put(key, phDeviceHandle.getValue()); return key; @@ -104,15 +83,4 @@ public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor { return ret; } - - @RequiredArgsConstructor - public static class CheckProxy implements InvocationHandler { - private final SdfLibrary sdfLibrary; - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - return null; - } - } - } diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/lib/SunyardSdfLibrary.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/lib/SunyardSdfLibrary.java index 3152f58..7e5d5da 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/lib/SunyardSdfLibrary.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/lib/SunyardSdfLibrary.java @@ -1,5 +1,6 @@ package com.sunyard.chsm.sdf.lib; +import com.sun.jna.Native; import com.sun.jna.ptr.PointerByReference; /** @@ -8,6 +9,7 @@ import com.sun.jna.ptr.PointerByReference; */ public interface SunyardSdfLibrary extends SdfLibrary { + SunyardSdfLibrary INSTANCE = Native.load("sdf", SunyardSdfLibrary.class); /** * 打开设备 diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/model/EccSignature.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/model/EccSignature.java index b809193..1e03103 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/model/EccSignature.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/model/EccSignature.java @@ -1,9 +1,12 @@ package com.sunyard.chsm.sdf.model; +import com.sunyard.chsm.utils.CodecUtils; +import com.sunyard.chsm.utils.gm.BCSM2Utils; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.IOException; import java.util.Arrays; /** @@ -22,6 +25,19 @@ public class EccSignature { // 签名的 s 部分 private byte[] s; + + public String getRawSignHex() { + return CodecUtils.encodeHex(getRawSignBytes()); + } + + public byte[] getDerSignBytes() { + try { + return BCSM2Utils.encodeSM2SignToDER(getRawSignBytes()); + } catch (IOException e) { + throw new IllegalArgumentException("ECC签名数据格式错误"); + } + } + public byte[] getRawSignBytes() { byte[] signData = new byte[r.length + s.length]; System.arraycopy(r, 0, signData, 0, r.length); @@ -38,8 +54,12 @@ public class EccSignature { public static EccSignature fromBytes(byte[] sign) { if (sign == null || sign.length == 0) { - return null; + throw new IllegalArgumentException("ECC签名数据格式错误"); } + if (sign.length >= 70 && sign.length <= 75) { + sign = BCSM2Utils.decodeDERSM2Sign(sign); + } + if (sign.length == 64) { byte[] r = Arrays.copyOfRange(sign, 0, 32); byte[] s = Arrays.copyOfRange(sign, 32, 64); diff --git a/chsm-common/src/main/java/com/sunyard/chsm/service/TmkService.java b/chsm-common/src/main/java/com/sunyard/chsm/service/TmkService.java index 0212f69..a4669b7 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/service/TmkService.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/service/TmkService.java @@ -174,11 +174,10 @@ public class TmkService { public void checkSoftDeviceTmk() { - if (!isTmkInit() || !isEnableSoftDevice()) { + if (Objects.nonNull(getSoftDeviceEncTmk())) { return; } - byte[] softTmk = getSoftDeviceEncTmk(); - if (Objects.nonNull(softTmk)) { + if (!isTmkInit() || !isEnableSoftDevice()) { return; } log.warn("enabled soft device but no tmk in soft"); @@ -220,9 +219,17 @@ public class TmkService { return null; } - public boolean isTmkInit() { + private boolean tmkInit; + private boolean enableSoftDevice; + private byte[] softEncTmk; + + public synchronized boolean isTmkInit() { + if (tmkInit) { + return true; + } ParamConf conf = paramConfMapper.selectByKey(ParamConfKeyConstant.TMK_INIT); - return conf != null && String.valueOf(true).equals(conf.getValue()); + tmkInit = conf != null && String.valueOf(true).equals(conf.getValue()); + return tmkInit; } public boolean isEnableSoftDevice() { @@ -244,16 +251,20 @@ public class TmkService { } } - public byte[] getSoftDeviceEncTmk() { + public synchronized byte[] getSoftDeviceEncTmk() { boolean tmkInit = isTmkInit(); Assert.isTrue(tmkInit, "主密钥未初始化"); boolean enabled = isEnableSoftDevice(); Assert.isTrue(enabled, "未启用软设备"); + if (softEncTmk != null) { + return softEncTmk; + } ParamConf conf = paramConfMapper.selectByKey(ParamConfKeyConstant.SOFT_ENC_TMK); if (conf == null || ObjectUtils.isEmpty(conf.getValue())) { return null; } - return CodecUtils.decodeBase64(conf.getValue()); + softEncTmk = CodecUtils.decodeBase64(conf.getValue()); + return softEncTmk; } private void updateSoftDeviceEncTmk(byte[] encTmk) { diff --git a/chsm-web-manage/src/main/java/com/sunyard/chsm/sdf/SingleSdfApiService.java b/chsm-web-manage/src/main/java/com/sunyard/chsm/sdf/SingleSdfApiService.java index 2afde32..13bd6d0 100644 --- a/chsm-web-manage/src/main/java/com/sunyard/chsm/sdf/SingleSdfApiService.java +++ b/chsm-web-manage/src/main/java/com/sunyard/chsm/sdf/SingleSdfApiService.java @@ -4,7 +4,6 @@ import com.sunyard.chsm.enums.DeviceTmkStatus; import com.sunyard.chsm.mapper.SpDeviceMapper; import com.sunyard.chsm.model.dto.DeviceCheckRes; import com.sunyard.chsm.model.entity.Device; -import com.sunyard.chsm.sdf.adapter.BcSdfApiAdaptor; import com.sunyard.chsm.sdf.adapter.SdfApiAdapter; import com.sunyard.chsm.sdf.adapter.SdfApiAdapterFactory; import com.sunyard.chsm.sdf.context.AlgId; @@ -218,21 +217,17 @@ public class SingleSdfApiService implements SdfApiService, InitializingBean { Executors.newSingleThreadScheduledExecutor() .scheduleWithFixedDelay(() -> { boolean tmkInit = tmkService.isTmkInit(); - if (sdfApiAdapter != null) { - if (sdfApiAdapter instanceof BcSdfApiAdaptor) { - changeDevice(tmkInit); - return; - } - if (tmkInit && StringUtils.isEmpty(tmkHandle)) { - changeDevice(tmkInit); - return; - } - try { - DeviceInfo deviceInfo = sdfApiAdapter.getDeviceInfo(sessionHandle); - } catch (Exception ex) { - changeDevice(tmkInit); - } - } else { + if (sdfApiAdapter == null) { + changeDevice(tmkInit); + return; + } + if (tmkInit && StringUtils.isEmpty(tmkHandle)) { + changeDevice(tmkInit); + return; + } + try { + DeviceInfo deviceInfo = sdfApiAdapter.getDeviceInfo(sessionHandle); + } catch (Exception ex) { changeDevice(tmkInit); } }, 0L, 5L, TimeUnit.MINUTES); diff --git a/chsm-web-manage/src/main/java/com/sunyard/chsm/task/DeviceTask.java b/chsm-web-manage/src/main/java/com/sunyard/chsm/task/DeviceTask.java index 77bb3aa..81b6500 100644 --- a/chsm-web-manage/src/main/java/com/sunyard/chsm/task/DeviceTask.java +++ b/chsm-web-manage/src/main/java/com/sunyard/chsm/task/DeviceTask.java @@ -1,6 +1,5 @@ package com.sunyard.chsm.task; -import com.sun.jna.Platform; import com.sunyard.chsm.service.DeviceService; import com.sunyard.chsm.service.TmkService; import lombok.extern.slf4j.Slf4j; @@ -28,12 +27,14 @@ public class DeviceTask implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { - if (Platform.isLinux() || Platform.isWindows()) { - threadPoolTaskScheduler.scheduleWithFixedDelay(deviceService::checkDeviceStatus, Duration.ofMinutes(5L)); - threadPoolTaskScheduler.scheduleWithFixedDelay(tmkService::checkSoftDeviceTmk, Duration.ofMinutes(5L)); - } else { - log.warn("操作系统: {} 不支持启动检查设备状态定时任务", System.getProperty("os.name")); - } + threadPoolTaskScheduler.scheduleWithFixedDelay(deviceService::checkDeviceStatus, Duration.ofMinutes(5L)); + threadPoolTaskScheduler.scheduleWithFixedDelay(tmkService::checkSoftDeviceTmk, Duration.ofMinutes(5L)); +// if (Platform.isLinux() || Platform.isWindows()) { +// threadPoolTaskScheduler.scheduleWithFixedDelay(deviceService::checkDeviceStatus, Duration.ofMinutes(5L)); +// threadPoolTaskScheduler.scheduleWithFixedDelay(tmkService::checkSoftDeviceTmk, Duration.ofMinutes(5L)); +// } else { +// log.warn("操作系统: {} 不支持启动检查设备状态定时任务", System.getProperty("os.name")); +// } } } diff --git a/chsm-web-manage/src/main/resources/application.yml b/chsm-web-manage/src/main/resources/application.yml index a68f9ea..92618a0 100644 --- a/chsm-web-manage/src/main/resources/application.yml +++ b/chsm-web-manage/src/main/resources/application.yml @@ -140,7 +140,6 @@ logging: level: root: info com.sunyard.chsm.mapper: debug - com.sunyard.chsm.service.TmkService: debug # org.springframework.web: trace # config: classpath:log4j2.xml diff --git a/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiTest.java b/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiAdapterTest.java similarity index 70% rename from chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiTest.java rename to chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiAdapterTest.java index 09e1740..1c0a42a 100644 --- a/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiTest.java +++ b/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiAdapterTest.java @@ -11,12 +11,13 @@ import com.sunyard.chsm.sdf.model.EccCipher; import com.sunyard.chsm.sdf.model.EccKey; import com.sunyard.chsm.sdf.model.EccPriKey; import com.sunyard.chsm.sdf.model.EccPubKey; +import com.sunyard.chsm.sdf.model.EccSignature; import com.sunyard.chsm.utils.CodecUtils; import com.sunyard.chsm.utils.JsonUtils; import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import java.net.URL; @@ -28,36 +29,39 @@ import java.util.Optional; * @since 2024/12/12 */ @Slf4j -class SdfApiTest { +class SdfApiAdapterTest { - private final byte[] symKey = "nhkdhaksd4678787".getBytes(); - private final byte[] iv = "hjdashde83252i23".getBytes(); - private final String plain = "hello sdf api ,hello sdf api !&!"; - private final String ip1 = "172.16.18.41"; - private final int port = 8889; + private final static byte[] symKey = "nhkdhaksd4678787".getBytes(); + private final static byte[] iv = "hjdashde83252i23".getBytes(); + private final static String plain = "hello sdf api ,hello sdf api !&!"; + private final static String ip1 = "172.16.18.41"; + private final static int port = 8889; + private static final SdfApiAdapter bcAdapter = SdfApiAdapterFactory.getBcAdapter(); - private RpcSdfAdapter rpcSdfAdapter; - private String hd; - private String hs; - private EccPubKey pubKey; - private EccPriKey priKey; - private SdfApiAdapter bcAdapter = SdfApiAdapterFactory.getBcAdapter(); + private static RpcSdfAdapter rpcSdfAdapter; + private static String hd; + private static String hs; + private static EccPubKey pubKey; + private static EccPriKey priKey; - @BeforeEach - public void before() throws Exception { + + @BeforeAll + public static void before() throws Exception { JsonRpcHttpClient client = new JsonRpcHttpClient(JsonUtils.objectMapper(), new URL("http://172.16.18.46:9989/sdf/adapter"), Collections.emptyMap()); rpcSdfAdapter = ProxyUtil.createClientProxy( - getClass().getClassLoader(), RpcSdfAdapter.class, client); - this.hd = rpcSdfAdapter.openDevice(ip1, port, 3000, 3000, 0); - this.hs = rpcSdfAdapter.openSession(hd); + SdfApiAdapterTest.class.getClassLoader(), RpcSdfAdapter.class, client); + hd = rpcSdfAdapter.openDevice(ip1, port, 3000, 3000, 0); + hs = rpcSdfAdapter.openSession(hd); EccKey eccKey = rpcSdfAdapter.generateKeyPairECC(hs, AlgId.SGD_SM2_3); - pubKey = EccPubKey.fromBytes(eccKey.getPubKey()); - priKey = EccPriKey.fromBytes(eccKey.getPriKey()); + pubKey = com.sunyard.chsm.sdf.model.EccPubKey.fromBytes(eccKey.getPubKey()); + priKey = com.sunyard.chsm.sdf.model.EccPriKey.fromBytes(eccKey.getPriKey()); + log.info("public key: {}", pubKey.getPubKeyHex()); + log.info("private key: {}", CodecUtils.encodeHex(priKey.getD())); } - @AfterEach - public void after() { + @AfterAll + public static void after() { Optional.ofNullable(hs).ifPresent(rpcSdfAdapter::closeSession); Optional.ofNullable(hd).ifPresent(rpcSdfAdapter::closeDevice); } @@ -114,6 +118,21 @@ class SdfApiTest { Assertions.assertEquals(plain, new String(sm2Plain)); } + @Test + public void testSM2SignAndVerify() { + EccSignature bcSign = bcAdapter.externalSignECC("", priKey, plain.getBytes()); + log.info("bc sm2 signature: {}", bcSign.getRawSignHex()); + boolean sdfVerified = rpcSdfAdapter.externalVerifyECC(hs, pubKey, plain.getBytes(), bcSign); + log.info("sdf sm2 verified: {}", sdfVerified); + Assertions.assertTrue(sdfVerified); + + EccSignature sdfSign = rpcSdfAdapter.externalSignECC(hs, priKey, plain.getBytes()); + log.info("sdf sm2 signature: {}", sdfSign.getRawSignHex()); + boolean bcVerified = bcAdapter.externalVerifyECC("", pubKey, plain.getBytes(), sdfSign); + log.info("bc sm2 verified: {}", bcVerified); + Assertions.assertTrue(bcVerified); + } + @Test public void testHash() { String newSession = rpcSdfAdapter.openSession(hd); @@ -147,5 +166,11 @@ class SdfApiTest { Assertions.assertArrayEquals(sdfMac, bcMac); } + @Test + public void testRandom() { + byte[] r = rpcSdfAdapter.generateRandom(hs, 64); + Assertions.assertEquals(64, r.length); + } + } diff --git a/pom.xml b/pom.xml index fceb96f..1b45f69 100644 --- a/pom.xml +++ b/pom.xml @@ -42,12 +42,6 @@ junit test - - com.github.briandilley.jsonrpc4j - jsonrpc4j - 1.6 - test -