This commit is contained in:
liulu 2024-12-13 14:32:58 +08:00
parent f2720fdb83
commit 8f997d2a00
14 changed files with 230 additions and 132 deletions

View File

@ -57,6 +57,11 @@
<groupId>net.java.dev.jna</groupId> <groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId> <artifactId>jna</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.github.briandilley.jsonrpc4j</groupId>
<artifactId>jsonrpc4j</artifactId>
<version>1.6</version>
</dependency>
</dependencies> </dependencies>

View File

@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.ApplicationRunner;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
@ -34,6 +35,7 @@ import java.util.stream.Collectors;
* @since 2024/12/2 * @since 2024/12/2
*/ */
@Slf4j @Slf4j
@Component
public class IpFilter extends OncePerRequestFilter implements ApplicationRunner { public class IpFilter extends OncePerRequestFilter implements ApplicationRunner {
public static List<String> whiteIps = new ArrayList<>(); public static List<String> whiteIps = new ArrayList<>();
@ -75,7 +77,7 @@ public class IpFilter extends OncePerRequestFilter implements ApplicationRunner
if (enableWhiteIp) { if (enableWhiteIp) {
syncWhiteIps(); syncWhiteIps();
} }
}, 0L, 5L, TimeUnit.MINUTES); }, 1L, 5L, TimeUnit.MINUTES);
} }

View File

@ -12,13 +12,11 @@ import com.sunyard.chsm.utils.gm.BCECUtils;
import com.sunyard.chsm.utils.gm.BCSM2Utils; import com.sunyard.chsm.utils.gm.BCSM2Utils;
import com.sunyard.chsm.utils.gm.BCSM4Utils; import com.sunyard.chsm.utils.gm.BCSM4Utils;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.NullDigest;
import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters; 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.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.ECPoint;
@ -29,6 +27,7 @@ import java.math.BigInteger;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -135,28 +134,69 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
} }
} }
private static final SecureRandom RANDOM = new SecureRandom();
@Override @Override
public EccSignature externalSignECC(String sessionHandle, EccPriKey privateKey, byte[] pucData) { public EccSignature externalSignECC(String sessionHandle, EccPriKey privateKey, byte[] pucData) {
ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(privateKey.getD()); ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(privateKey.getD());
try {
SM2Signer signer = new SM2Signer(new NullDigest()); BigInteger n = pri.getParameters().getN();
signer.init(true, pri); BigInteger d = pri.getD();
signer.update(pucData, 0, pucData.length);
byte[] signature = signer.generateSignature(); BigInteger e = new BigInteger(1, pucData);
return EccSignature.fromBytes(signature); BigInteger r, s = null;
} catch (CryptoException e) {
throw new IllegalArgumentException(e); 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 @Override
public boolean externalVerifyECC(String sessionHandle, EccPubKey publicKey, byte[] pucData, EccSignature pucSignature) { public boolean externalVerifyECC(String sessionHandle, EccPubKey publicKey, byte[] pucData, EccSignature pucSignature) {
ECPublicKeyParameters pub = BCECUtils.createECPublicKeyParameters(publicKey.getX(), publicKey.getY()); ECPublicKeyParameters pub = BCECUtils.createECPublicKeyParameters(publicKey.getX(), publicKey.getY());
SM2Signer verifier = new SM2Signer(new NullDigest()); if (pucData.length != 32) {
verifier.init(false, pub); throw new IllegalArgumentException("Hash length must be 32 bytes");
// 验证数据 }
verifier.update(pucData, 0, pucData.length); ECDomainParameters domainParams = pub.getParameters();
return verifier.verifySignature(pucSignature.getRawSignBytes()); 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 @Override

View File

@ -1,15 +1,26 @@
package com.sunyard.chsm.sdf.adapter; 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.enums.ManufacturerModelEnum;
import com.sunyard.chsm.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.Assert; 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; import java.util.Objects;
/** /**
* @author liulu * @author liulu
* @since 2024/11/5 * @since 2024/11/5
*/ */
@Slf4j
public class SdfApiAdapterFactory { public class SdfApiAdapterFactory {
@ -28,11 +39,36 @@ public class SdfApiAdapterFactory {
} }
switch (modelEnum) { switch (modelEnum) {
case enc001: case enc001:
return new SunyardJnaSdfAdaptor(ip, port); return Platform.isMac() ? getProxyRcpAdapter(ip, port) : new SunyardJnaSdfAdaptor(ip, port);
default: default:
throw new UnsupportedOperationException("不支持的设备型号: " + model); 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);
}
);
}
} }

View File

@ -1,22 +1,17 @@
package com.sunyard.chsm.sdf.adapter; package com.sunyard.chsm.sdf.adapter;
import com.sun.jna.Native;
import com.sun.jna.ptr.PointerByReference; import com.sun.jna.ptr.PointerByReference;
import com.sunyard.chsm.sdf.context.AlgId; import com.sunyard.chsm.sdf.context.AlgId;
import com.sunyard.chsm.sdf.context.SdrCode; import com.sunyard.chsm.sdf.context.SdrCode;
import com.sunyard.chsm.sdf.context.SunyardAlgId; import com.sunyard.chsm.sdf.context.SunyardAlgId;
import com.sunyard.chsm.sdf.lib.SdfLibrary; import com.sunyard.chsm.sdf.lib.SdfLibrary;
import com.sunyard.chsm.sdf.lib.SunyardSdfLibrary; import com.sunyard.chsm.sdf.lib.SunyardSdfLibrary;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Map; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* @author liulu * @author liulu
@ -25,64 +20,48 @@ import java.util.concurrent.ConcurrentHashMap;
@Slf4j @Slf4j
public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor { public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor {
private static final Map<String, SunyardSdfLibrary> SDF_LIB_MAP = new ConcurrentHashMap<>();
private final String ip; private final String ip;
private final Integer port; private final Integer port;
private String libName;
private final Integer connTimeout; private final Integer connTimeout;
private final Integer dealTimeout; private final Integer dealTimeout;
public SunyardJnaSdfAdaptor(String ip) {
this(ip, 8889, "sdf");
}
public SunyardJnaSdfAdaptor(String ip, int port) { public SunyardJnaSdfAdaptor(String ip, int port) {
this(ip, port, "sdf"); this(ip, port, 3000, 3000);
} }
public SunyardJnaSdfAdaptor(String ip, int port, String libName) { public SunyardJnaSdfAdaptor(String ip, int port, int connTimeout, int dealTimeout) {
this(ip, port, libName, 3000, 3000);
}
public SunyardJnaSdfAdaptor(String ip, int port, String libName, int connTimeout, int dealTimeout) {
super((SdfLibrary) Proxy.newProxyInstance(ClassUtils.getDefaultClassLoader(), super((SdfLibrary) Proxy.newProxyInstance(ClassUtils.getDefaultClassLoader(),
new Class[]{SdfLibrary.class}, new Class[]{SdfLibrary.class},
new InvocationHandler() { (proxy, method, args) -> {
private final SunyardSdfLibrary sunyardSdfLibrary; Object res = method.invoke(SunyardSdfLibrary.INSTANCE, args);
if (!(res instanceof Integer)) {
{
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));
}
}
return res; 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.ip = ip;
this.port = port; this.port = port;
this.libName = libName;
this.connTimeout = connTimeout; this.connTimeout = connTimeout;
this.dealTimeout = dealTimeout; this.dealTimeout = dealTimeout;
} }
@Override @Override
public String openDevice() { public String openDevice() {
SunyardSdfLibrary sunyardSdfLibrary = SDF_LIB_MAP.computeIfAbsent(libName, k -> Native.load(libName, SunyardSdfLibrary.class));
PointerByReference phDeviceHandle = new PointerByReference(); 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(); String key = UUID.randomUUID().toString();
DEVICE_HANDLE_CONTEXT.put(key, phDeviceHandle.getValue()); DEVICE_HANDLE_CONTEXT.put(key, phDeviceHandle.getValue());
return key; return key;
@ -104,15 +83,4 @@ public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor {
return ret; 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;
}
}
} }

View File

@ -1,5 +1,6 @@
package com.sunyard.chsm.sdf.lib; package com.sunyard.chsm.sdf.lib;
import com.sun.jna.Native;
import com.sun.jna.ptr.PointerByReference; import com.sun.jna.ptr.PointerByReference;
/** /**
@ -8,6 +9,7 @@ import com.sun.jna.ptr.PointerByReference;
*/ */
public interface SunyardSdfLibrary extends SdfLibrary { public interface SunyardSdfLibrary extends SdfLibrary {
SunyardSdfLibrary INSTANCE = Native.load("sdf", SunyardSdfLibrary.class);
/** /**
* 打开设备 * 打开设备

View File

@ -1,9 +1,12 @@
package com.sunyard.chsm.sdf.model; package com.sunyard.chsm.sdf.model;
import com.sunyard.chsm.utils.CodecUtils;
import com.sunyard.chsm.utils.gm.BCSM2Utils;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
/** /**
@ -22,6 +25,19 @@ public class EccSignature {
// 签名的 s 部分 // 签名的 s 部分
private byte[] 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() { public byte[] getRawSignBytes() {
byte[] signData = new byte[r.length + s.length]; byte[] signData = new byte[r.length + s.length];
System.arraycopy(r, 0, signData, 0, r.length); System.arraycopy(r, 0, signData, 0, r.length);
@ -38,8 +54,12 @@ public class EccSignature {
public static EccSignature fromBytes(byte[] sign) { public static EccSignature fromBytes(byte[] sign) {
if (sign == null || sign.length == 0) { 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) { if (sign.length == 64) {
byte[] r = Arrays.copyOfRange(sign, 0, 32); byte[] r = Arrays.copyOfRange(sign, 0, 32);
byte[] s = Arrays.copyOfRange(sign, 32, 64); byte[] s = Arrays.copyOfRange(sign, 32, 64);

View File

@ -174,11 +174,10 @@ public class TmkService {
public void checkSoftDeviceTmk() { public void checkSoftDeviceTmk() {
if (!isTmkInit() || !isEnableSoftDevice()) { if (Objects.nonNull(getSoftDeviceEncTmk())) {
return; return;
} }
byte[] softTmk = getSoftDeviceEncTmk(); if (!isTmkInit() || !isEnableSoftDevice()) {
if (Objects.nonNull(softTmk)) {
return; return;
} }
log.warn("enabled soft device but no tmk in soft"); log.warn("enabled soft device but no tmk in soft");
@ -220,9 +219,17 @@ public class TmkService {
return null; 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); 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() { public boolean isEnableSoftDevice() {
@ -244,16 +251,20 @@ public class TmkService {
} }
} }
public byte[] getSoftDeviceEncTmk() { public synchronized byte[] getSoftDeviceEncTmk() {
boolean tmkInit = isTmkInit(); boolean tmkInit = isTmkInit();
Assert.isTrue(tmkInit, "主密钥未初始化"); Assert.isTrue(tmkInit, "主密钥未初始化");
boolean enabled = isEnableSoftDevice(); boolean enabled = isEnableSoftDevice();
Assert.isTrue(enabled, "未启用软设备"); Assert.isTrue(enabled, "未启用软设备");
if (softEncTmk != null) {
return softEncTmk;
}
ParamConf conf = paramConfMapper.selectByKey(ParamConfKeyConstant.SOFT_ENC_TMK); ParamConf conf = paramConfMapper.selectByKey(ParamConfKeyConstant.SOFT_ENC_TMK);
if (conf == null || ObjectUtils.isEmpty(conf.getValue())) { if (conf == null || ObjectUtils.isEmpty(conf.getValue())) {
return null; return null;
} }
return CodecUtils.decodeBase64(conf.getValue()); softEncTmk = CodecUtils.decodeBase64(conf.getValue());
return softEncTmk;
} }
private void updateSoftDeviceEncTmk(byte[] encTmk) { private void updateSoftDeviceEncTmk(byte[] encTmk) {

View File

@ -4,7 +4,6 @@ import com.sunyard.chsm.enums.DeviceTmkStatus;
import com.sunyard.chsm.mapper.SpDeviceMapper; import com.sunyard.chsm.mapper.SpDeviceMapper;
import com.sunyard.chsm.model.dto.DeviceCheckRes; import com.sunyard.chsm.model.dto.DeviceCheckRes;
import com.sunyard.chsm.model.entity.Device; 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.SdfApiAdapter;
import com.sunyard.chsm.sdf.adapter.SdfApiAdapterFactory; import com.sunyard.chsm.sdf.adapter.SdfApiAdapterFactory;
import com.sunyard.chsm.sdf.context.AlgId; import com.sunyard.chsm.sdf.context.AlgId;
@ -218,21 +217,17 @@ public class SingleSdfApiService implements SdfApiService, InitializingBean {
Executors.newSingleThreadScheduledExecutor() Executors.newSingleThreadScheduledExecutor()
.scheduleWithFixedDelay(() -> { .scheduleWithFixedDelay(() -> {
boolean tmkInit = tmkService.isTmkInit(); boolean tmkInit = tmkService.isTmkInit();
if (sdfApiAdapter != null) { if (sdfApiAdapter == null) {
if (sdfApiAdapter instanceof BcSdfApiAdaptor) { changeDevice(tmkInit);
changeDevice(tmkInit); return;
return; }
} if (tmkInit && StringUtils.isEmpty(tmkHandle)) {
if (tmkInit && StringUtils.isEmpty(tmkHandle)) { changeDevice(tmkInit);
changeDevice(tmkInit); return;
return; }
} try {
try { DeviceInfo deviceInfo = sdfApiAdapter.getDeviceInfo(sessionHandle);
DeviceInfo deviceInfo = sdfApiAdapter.getDeviceInfo(sessionHandle); } catch (Exception ex) {
} catch (Exception ex) {
changeDevice(tmkInit);
}
} else {
changeDevice(tmkInit); changeDevice(tmkInit);
} }
}, 0L, 5L, TimeUnit.MINUTES); }, 0L, 5L, TimeUnit.MINUTES);

View File

@ -1,6 +1,5 @@
package com.sunyard.chsm.task; package com.sunyard.chsm.task;
import com.sun.jna.Platform;
import com.sunyard.chsm.service.DeviceService; import com.sunyard.chsm.service.DeviceService;
import com.sunyard.chsm.service.TmkService; import com.sunyard.chsm.service.TmkService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -28,12 +27,14 @@ public class DeviceTask implements InitializingBean {
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (Platform.isLinux() || Platform.isWindows()) { threadPoolTaskScheduler.scheduleWithFixedDelay(deviceService::checkDeviceStatus, Duration.ofMinutes(5L));
threadPoolTaskScheduler.scheduleWithFixedDelay(deviceService::checkDeviceStatus, Duration.ofMinutes(5L)); threadPoolTaskScheduler.scheduleWithFixedDelay(tmkService::checkSoftDeviceTmk, Duration.ofMinutes(5L));
threadPoolTaskScheduler.scheduleWithFixedDelay(tmkService::checkSoftDeviceTmk, Duration.ofMinutes(5L)); // if (Platform.isLinux() || Platform.isWindows()) {
} else { // threadPoolTaskScheduler.scheduleWithFixedDelay(deviceService::checkDeviceStatus, Duration.ofMinutes(5L));
log.warn("操作系统: {} 不支持启动检查设备状态定时任务", System.getProperty("os.name")); // threadPoolTaskScheduler.scheduleWithFixedDelay(tmkService::checkSoftDeviceTmk, Duration.ofMinutes(5L));
} // } else {
// log.warn("操作系统: {} 不支持启动检查设备状态定时任务", System.getProperty("os.name"));
// }
} }
} }

View File

@ -140,7 +140,6 @@ logging:
level: level:
root: info root: info
com.sunyard.chsm.mapper: debug com.sunyard.chsm.mapper: debug
com.sunyard.chsm.service.TmkService: debug
# org.springframework.web: trace # org.springframework.web: trace
# config: classpath:log4j2.xml # config: classpath:log4j2.xml

View File

@ -11,12 +11,13 @@ import com.sunyard.chsm.sdf.model.EccCipher;
import com.sunyard.chsm.sdf.model.EccKey; import com.sunyard.chsm.sdf.model.EccKey;
import com.sunyard.chsm.sdf.model.EccPriKey; import com.sunyard.chsm.sdf.model.EccPriKey;
import com.sunyard.chsm.sdf.model.EccPubKey; 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.CodecUtils;
import com.sunyard.chsm.utils.JsonUtils; import com.sunyard.chsm.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j; 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.Assertions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.net.URL; import java.net.URL;
@ -28,36 +29,39 @@ import java.util.Optional;
* @since 2024/12/12 * @since 2024/12/12
*/ */
@Slf4j @Slf4j
class SdfApiTest { class SdfApiAdapterTest {
private final byte[] symKey = "nhkdhaksd4678787".getBytes(); private final static byte[] symKey = "nhkdhaksd4678787".getBytes();
private final byte[] iv = "hjdashde83252i23".getBytes(); private final static byte[] iv = "hjdashde83252i23".getBytes();
private final String plain = "hello sdf api ,hello sdf api !&!"; private final static String plain = "hello sdf api ,hello sdf api !&!";
private final String ip1 = "172.16.18.41"; private final static String ip1 = "172.16.18.41";
private final int port = 8889; private final static int port = 8889;
private static final SdfApiAdapter bcAdapter = SdfApiAdapterFactory.getBcAdapter();
private RpcSdfAdapter rpcSdfAdapter; private static RpcSdfAdapter rpcSdfAdapter;
private String hd; private static String hd;
private String hs; private static String hs;
private EccPubKey pubKey; private static EccPubKey pubKey;
private EccPriKey priKey; private static EccPriKey priKey;
private SdfApiAdapter bcAdapter = SdfApiAdapterFactory.getBcAdapter();
@BeforeEach
public void before() throws Exception { @BeforeAll
public static void before() throws Exception {
JsonRpcHttpClient client = new JsonRpcHttpClient(JsonUtils.objectMapper(), JsonRpcHttpClient client = new JsonRpcHttpClient(JsonUtils.objectMapper(),
new URL("http://172.16.18.46:9989/sdf/adapter"), Collections.emptyMap()); new URL("http://172.16.18.46:9989/sdf/adapter"), Collections.emptyMap());
rpcSdfAdapter = ProxyUtil.createClientProxy( rpcSdfAdapter = ProxyUtil.createClientProxy(
getClass().getClassLoader(), RpcSdfAdapter.class, client); SdfApiAdapterTest.class.getClassLoader(), RpcSdfAdapter.class, client);
this.hd = rpcSdfAdapter.openDevice(ip1, port, 3000, 3000, 0); hd = rpcSdfAdapter.openDevice(ip1, port, 3000, 3000, 0);
this.hs = rpcSdfAdapter.openSession(hd); hs = rpcSdfAdapter.openSession(hd);
EccKey eccKey = rpcSdfAdapter.generateKeyPairECC(hs, AlgId.SGD_SM2_3); EccKey eccKey = rpcSdfAdapter.generateKeyPairECC(hs, AlgId.SGD_SM2_3);
pubKey = EccPubKey.fromBytes(eccKey.getPubKey()); pubKey = com.sunyard.chsm.sdf.model.EccPubKey.fromBytes(eccKey.getPubKey());
priKey = EccPriKey.fromBytes(eccKey.getPriKey()); 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 @AfterAll
public void after() { public static void after() {
Optional.ofNullable(hs).ifPresent(rpcSdfAdapter::closeSession); Optional.ofNullable(hs).ifPresent(rpcSdfAdapter::closeSession);
Optional.ofNullable(hd).ifPresent(rpcSdfAdapter::closeDevice); Optional.ofNullable(hd).ifPresent(rpcSdfAdapter::closeDevice);
} }
@ -114,6 +118,21 @@ class SdfApiTest {
Assertions.assertEquals(plain, new String(sm2Plain)); 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 @Test
public void testHash() { public void testHash() {
String newSession = rpcSdfAdapter.openSession(hd); String newSession = rpcSdfAdapter.openSession(hd);
@ -147,5 +166,11 @@ class SdfApiTest {
Assertions.assertArrayEquals(sdfMac, bcMac); Assertions.assertArrayEquals(sdfMac, bcMac);
} }
@Test
public void testRandom() {
byte[] r = rpcSdfAdapter.generateRandom(hs, 64);
Assertions.assertEquals(64, r.length);
}
} }

View File

@ -42,12 +42,6 @@
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.github.briandilley.jsonrpc4j</groupId>
<artifactId>jsonrpc4j</artifactId>
<version>1.6</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>