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>
<artifactId>jna</artifactId>
</dependency>
<dependency>
<groupId>com.github.briandilley.jsonrpc4j</groupId>
<artifactId>jsonrpc4j</artifactId>
<version>1.6</version>
</dependency>
</dependencies>

View File

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

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.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

View File

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

View File

@ -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<String, SunyardSdfLibrary> 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;
}
}
}

View File

@ -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);
/**
* 打开设备

View File

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

View File

@ -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) {

View File

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

View File

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

View File

@ -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

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.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);
}
}

View File

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