From 6cdf222def5ed47622eee2a00d3ecc657a1d41f8 Mon Sep 17 00:00:00 2001 From: liulu Date: Wed, 25 Dec 2024 15:45:35 +0800 Subject: [PATCH] =?UTF-8?q?hash=20=E8=BF=90=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sdf/adapter/SdfApiAdapterFactory.java | 2 +- .../sdf/adapter/SunyardJnaSdfAdaptor.java | 2 +- .../com/sunyard/chsm/param/AppTokenReq.java | 2 +- .../com/sunyard/chsm/param/GenRandomReq.java | 23 ++++ .../com/sunyard/chsm/param/GenRandomResp.java | 16 +++ .../java/com/sunyard/chsm/param/HashReq.java | 5 +- .../java/com/sunyard/chsm/param/HashResp.java | 3 + .../chsm/controller/AppLoginController.java | 6 -- .../chsm/controller/HashController.java | 100 ++++++++++++++++++ .../chsm/controller/RandomController.java | 43 ++++++++ .../sunyard/chsm/service/AppLoginService.java | 29 +---- .../sunyard/chsm/service/SymKeyService.java | 21 +--- .../src/test/java/api/BaseTest.java | 13 ++- .../src/test/java/api/HashTest.java | 62 +++++++++++ .../src/test/java/api/SymKeyTest.java | 19 ++-- 15 files changed, 275 insertions(+), 71 deletions(-) create mode 100644 chsm-params/src/main/java/com/sunyard/chsm/param/GenRandomReq.java create mode 100644 chsm-params/src/main/java/com/sunyard/chsm/param/GenRandomResp.java create mode 100644 chsm-web-server/src/main/java/com/sunyard/chsm/controller/RandomController.java create mode 100644 chsm-web-server/src/test/java/api/HashTest.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 abd329a..098d225 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 @@ -63,7 +63,7 @@ public class SdfApiAdapterFactory { new Class[]{SdfApiAdapter.class}, (proxy, method, args) -> { if (Objects.equals(method.getName(), "openDevice")) { - return rpcSdfAdapter.openDevice(ip, port, 3000, 3000, 0); + return rpcSdfAdapter.openDevice(ip, port, 3000, 10000, 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 3c3ac86..5dc7304 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 @@ -33,7 +33,7 @@ public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor { private final Integer dealTimeout; public SunyardJnaSdfAdaptor(String ip, int port) { - this(ip, port, 3000, 3000); + this(ip, port, 3000, 10000); } public SunyardJnaSdfAdaptor(String ip, int port, int connTimeout, int dealTimeout) { diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/AppTokenReq.java b/chsm-params/src/main/java/com/sunyard/chsm/param/AppTokenReq.java index 7429ab3..b07c005 100644 --- a/chsm-params/src/main/java/com/sunyard/chsm/param/AppTokenReq.java +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/AppTokenReq.java @@ -23,7 +23,7 @@ public class AppTokenReq { * 时间戳毫秒数,与服务器时间不能超过5分钟 */ @NotNull - private Long random; + private Long timestamp; /** * 使用appKey+random+appSecret作为原文,使用appSecret作为key,根据HmacSM3算法计算得到hmac值,转为Hex编码 */ diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/GenRandomReq.java b/chsm-params/src/main/java/com/sunyard/chsm/param/GenRandomReq.java new file mode 100644 index 0000000..486a5f6 --- /dev/null +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/GenRandomReq.java @@ -0,0 +1,23 @@ +package com.sunyard.chsm.param; + +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author liulu + * @since 2024/12/25 + */ +@Data +public class GenRandomReq { + + // 随机数长度, 最大10240 + @NotNull(message = "随机数长度不能为空") + @Min(value = 1L, message = "随机数长度最小为1") + @Max(value = 10240L, message = "随机数长度最大为10240") + private Integer length; + + +} diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/GenRandomResp.java b/chsm-params/src/main/java/com/sunyard/chsm/param/GenRandomResp.java new file mode 100644 index 0000000..8829d4c --- /dev/null +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/GenRandomResp.java @@ -0,0 +1,16 @@ +package com.sunyard.chsm.param; + +import lombok.Data; + +/** + * @author liulu + * @since 2024/12/25 + */ +@Data +public class GenRandomResp { + + // 随机数, base64编码 + private String random; + + +} diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/HashReq.java b/chsm-params/src/main/java/com/sunyard/chsm/param/HashReq.java index 13058ab..313d9df 100644 --- a/chsm-params/src/main/java/com/sunyard/chsm/param/HashReq.java +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/HashReq.java @@ -3,15 +3,14 @@ package com.sunyard.chsm.param; import com.sunyard.chsm.enums.HashAlg; import lombok.Data; -import javax.validation.constraints.NotBlank; - @Data public class HashReq { // 明文,使用Base64编码 - @NotBlank(message = "明文不能为空") private String plainData; + // 句柄, 多包计算Init后返回 + private String handle; // Hash算法, 默认SM3 private HashAlg alg = HashAlg.SM3; diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/HashResp.java b/chsm-params/src/main/java/com/sunyard/chsm/param/HashResp.java index c096316..f57625c 100644 --- a/chsm-params/src/main/java/com/sunyard/chsm/param/HashResp.java +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/HashResp.java @@ -5,6 +5,9 @@ import lombok.Data; @Data public class HashResp { + // 句柄, 多包计算Init后返回 + private String handle; + // mac值,使用Base64编码 private String hash; diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/controller/AppLoginController.java b/chsm-web-server/src/main/java/com/sunyard/chsm/controller/AppLoginController.java index 054c6c1..9121812 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/controller/AppLoginController.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/controller/AppLoginController.java @@ -41,11 +41,5 @@ public class AppLoginController { return R.data(appToken); } - @PostMapping("/appUser/getAppTokenTest") - public R getAppTokenForTest(@Valid @RequestBody AppTokenReq appTokenReq) { - AppTokenResp appToken = appLoginService.getAppTokenForTest(appTokenReq); - return R.data(appToken); - } - } diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/controller/HashController.java b/chsm-web-server/src/main/java/com/sunyard/chsm/controller/HashController.java index b3f313d..d361f89 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/controller/HashController.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/controller/HashController.java @@ -2,17 +2,29 @@ package com.sunyard.chsm.controller; import com.sunyard.chsm.auth.AuthCode; import com.sunyard.chsm.constant.AuthCodeConst; +import com.sunyard.chsm.constant.CryptoConst; import com.sunyard.chsm.model.R; import com.sunyard.chsm.param.HashReq; import com.sunyard.chsm.param.HashResp; +import com.sunyard.chsm.pool.DeviceManager; +import com.sunyard.chsm.pool.TMKContext; import com.sunyard.chsm.sdf.SdfApiService; +import com.sunyard.chsm.sdf.adapter.SdfApiAdapter; +import com.sunyard.chsm.sdf.context.AlgId; +import com.sunyard.chsm.sdf.model.EccPubKey; import com.sunyard.chsm.utils.CodecUtils; +import org.springframework.util.Assert; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; /** * 杂凑运算类接口 @@ -25,6 +37,8 @@ public class HashController { @Resource private SdfApiService sdfApiService; + @Resource + private DeviceManager deviceManager; /** * 计算Hash @@ -35,7 +49,9 @@ public class HashController { @PostMapping("/hash") @AuthCode(AuthCodeConst.cal_hash) public R hash(@Valid @RequestBody HashReq req) { + Assert.hasText(req.getPlainData(), "原文不能为空"); byte[] bytes = CodecUtils.decodeBase64(req.getPlainData()); + Assert.isTrue(bytes.length <= 8192, "原文长度最大支持8192"); byte[] pubkey = CodecUtils.decodeBase64(req.getPubKey()); byte[] userId = CodecUtils.decodeBase64(req.getUserId()); byte[] hash = sdfApiService.hash(bytes, pubkey, userId); @@ -44,5 +60,89 @@ public class HashController { return R.data(resp); } + private static final Map HANDLE_MAP = new ConcurrentHashMap<>(); + + + /** + * 多包HashInit + * + * @param req + * @return + */ + @PostMapping("/multi/package/hash/init") + @AuthCode(AuthCodeConst.cal_hash) + public R hashInit(@Valid @RequestBody HashReq req) { + byte[] pubKey = CodecUtils.decodeBase64(req.getPubKey()); + byte[] userId = CodecUtils.decodeBase64(req.getUserId()); + TMKContext context = deviceManager.chooseOne(); + try { + SdfApiAdapter sdf = context.getSdfApiAdapter(); + TMKContext newContext = new TMKContext(); + newContext.setDeviceHandle(context.getDeviceHandle()); + newContext.setSdfApiAdapter(sdf); + String hs = sdf.openSession(context.getDeviceHandle()); + newContext.setSessionHandle(hs); + EccPubKey eccPubKey = pubKey == null || pubKey.length == 0 ? null : EccPubKey.fromBytes(pubKey); + byte[] finalUserId = Objects.nonNull(pubKey) && Objects.isNull(userId) ? CryptoConst.USER_ID : userId; + sdf.hashInit(hs, AlgId.SGD_SM3, eccPubKey, finalUserId); + String handle = UUID.randomUUID().toString(); + HANDLE_MAP.put(handle, newContext); + + HashResp resp = new HashResp(); + resp.setHandle(handle); + return R.data(resp); + } finally { + Optional.ofNullable(context.getPool()) + .ifPresent(it -> { + context.setPool(null); + it.returnObject(context); + }); + } + } + + /** + * 多包Hash update + * + * @param req + * @return + */ + @PostMapping("/multi/package/hash/update") + @AuthCode(AuthCodeConst.cal_hash) + public R hashUpdate(@Valid @RequestBody HashReq req) { + Assert.hasText(req.getPlainData(), "原文不能为空"); + Assert.hasText(req.getHandle(), "句柄不能为空"); + byte[] bytes = CodecUtils.decodeBase64(req.getPlainData()); + Assert.isTrue(bytes.length <= 8192, "原文长度最大支持8192"); + TMKContext context = HANDLE_MAP.get(req.getHandle()); + Assert.notNull(context, "句柄引用不存在"); + SdfApiAdapter sdf = context.getSdfApiAdapter(); + sdf.hashUpdate(context.getSessionHandle(), bytes); + HashResp resp = new HashResp(); + resp.setHandle(req.getHandle()); + return R.data(resp); + } + + + /** + * 多包Hash finish + * + * @param req + * @return + */ + @PostMapping("/multi/package/hash/finish") + @AuthCode(AuthCodeConst.cal_hash) + public R hashFinish(@Valid @RequestBody HashReq req) { + Assert.hasText(req.getHandle(), "句柄不能为空"); + TMKContext context = HANDLE_MAP.remove(req.getHandle()); + Assert.notNull(context, "句柄引用不存在"); + SdfApiAdapter sdf = context.getSdfApiAdapter(); + byte[] hash = sdf.hashFinish(context.getSessionHandle()); + sdf.closeSession(context.getSessionHandle()); + HashResp resp = new HashResp(); + resp.setHandle(req.getHandle()); + resp.setHash(CodecUtils.encodeBase64(hash)); + return R.data(resp); + } + } diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/controller/RandomController.java b/chsm-web-server/src/main/java/com/sunyard/chsm/controller/RandomController.java new file mode 100644 index 0000000..9462b0e --- /dev/null +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/controller/RandomController.java @@ -0,0 +1,43 @@ +package com.sunyard.chsm.controller; + +import com.sunyard.chsm.auth.AuthCode; +import com.sunyard.chsm.constant.AuthCodeConst; +import com.sunyard.chsm.model.R; +import com.sunyard.chsm.param.GenRandomReq; +import com.sunyard.chsm.param.GenRandomResp; +import com.sunyard.chsm.sdf.SdfApiService; +import com.sunyard.chsm.utils.CodecUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 随机数接口 + * + * @author liulu + * @since 2024/12/25 + */ +@RestController +public class RandomController { + + @Resource + private SdfApiService sdfApiService; + + /** + * 获取随机数 + * + * @param req + * @return + */ + @PostMapping("/gen/random") + @AuthCode(AuthCodeConst.gen_random) + public R hash(@RequestBody GenRandomReq req) { + byte[] random = sdfApiService.generateRandom(req.getLength()); + GenRandomResp resp = new GenRandomResp(); + resp.setRandom(CodecUtils.encodeBase64(random)); + return R.data(resp); + } + +} diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/service/AppLoginService.java b/chsm-web-server/src/main/java/com/sunyard/chsm/service/AppLoginService.java index aabfa31..6c36508 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/service/AppLoginService.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/service/AppLoginService.java @@ -21,14 +21,7 @@ import org.springframework.stereotype.Service; import org.springframework.util.Assert; import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; /** @@ -50,7 +43,7 @@ public class AppLoginService { private AppServiceMapper appServiceMapper; public AppTokenResp getAppToken(AppTokenReq req) { - Long random = req.getRandom(); + Long random = req.getTimestamp(); long now = System.currentTimeMillis(); Assert.isTrue(now - random <= 5 * 60 * 1000, "请求已超时"); String appKey = req.getAppKey(); @@ -58,7 +51,7 @@ public class AppLoginService { Assert.isTrue(EnableStatus.ENABLED.getCode().equals(application.getStatus()), "此应用已停用"); String data = appKey + random + application.getAppSecret(); byte[] hmac = BCSM3Utils.hmac(application.getAppSecret().getBytes(), data.getBytes()); - String serverHmac = CodecUtils.encodeHex(hmac); + String serverHmac = CodecUtils.encodeBase64(hmac); if (!Objects.equals(req.getHmac(), serverHmac)) { log.warn("appKey: {}, req hmac: {}, server hmac: {}", appKey, req.getHmac(), serverHmac); throw new IllegalArgumentException("应用认证失败"); @@ -86,22 +79,6 @@ public class AppLoginService { .compact(); } - public AppTokenResp getAppTokenForTest(@Valid AppTokenReq req) { - -// Long random = req.getRandom(); -// long now = System.currentTimeMillis(); -// Assert.isTrue(now - random <= 5 * 60 * 1000, "请求已超时"); - Application application = applicationMapper.selectByAppKey(req.getAppKey()); - Assert.isTrue(EnableStatus.ENABLED.getCode().equals(application.getStatus()), "此应用已停用"); - if (!Objects.equals(req.getHmac(), application.getAppSecret())) { - log.warn("appKey: {}, req hmac: {},", req.getAppKey(), req.getHmac()); - throw new IllegalArgumentException("应用认证失败"); - } - AppTokenResp resp = new AppTokenResp(); - resp.setToken(genToken(application)); - return resp; - } - public AppUser verifyToken(String token) { Claims claims = Jwts.parser() diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/service/SymKeyService.java b/chsm-web-server/src/main/java/com/sunyard/chsm/service/SymKeyService.java index 1c858d3..2d1d7cb 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/service/SymKeyService.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/service/SymKeyService.java @@ -1,27 +1,12 @@ package com.sunyard.chsm.service; import com.sunyard.chsm.auth.UserContext; -import com.sunyard.chsm.enums.AlgMode; -import com.sunyard.chsm.enums.KeyAlg; -import com.sunyard.chsm.enums.KeyCategory; -import com.sunyard.chsm.enums.KeyStatus; -import com.sunyard.chsm.enums.KeyUsage; -import com.sunyard.chsm.enums.Padding; +import com.sunyard.chsm.enums.*; import com.sunyard.chsm.mapper.KeyInfoMapper; import com.sunyard.chsm.mapper.SpKeyRecordMapper; import com.sunyard.chsm.model.entity.KeyInfo; import com.sunyard.chsm.model.entity.KeyRecord; -import com.sunyard.chsm.param.SymDecryptReq; -import com.sunyard.chsm.param.SymDecryptResp; -import com.sunyard.chsm.param.SymEncryptReq; -import com.sunyard.chsm.param.SymEncryptResp; -import com.sunyard.chsm.param.SymHmacCheckReq; -import com.sunyard.chsm.param.SymHmacReq; -import com.sunyard.chsm.param.SymHmacResp; -import com.sunyard.chsm.param.SymMacCheckReq; -import com.sunyard.chsm.param.SymMacReq; -import com.sunyard.chsm.param.SymMacResp; -import com.sunyard.chsm.param.VerifyResp; +import com.sunyard.chsm.param.*; import com.sunyard.chsm.sdf.SdfApiService; import com.sunyard.chsm.sdf.context.AlgId; import com.sunyard.chsm.utils.CodecUtils; @@ -55,6 +40,7 @@ public class SymKeyService { iv = bytes; } byte[] plain = CodecUtils.decodeBase64(req.getPlainData()); + Assert.isTrue(plain.length <= 7680, "明文长度最大支持7680"); KeyInfo keyInfo = checkKey(req.getKeyId(), KeyUsage.ENCRYPT_DECRYPT); KeyAlg keyAlg = KeyAlg.of(keyInfo.getKeyAlg()); Assert.notNull(keyAlg, "数据异常"); @@ -98,6 +84,7 @@ public class SymKeyService { iv = bytes; } byte[] cipher = CodecUtils.decodeBase64(req.getCipherData()); + Assert.isTrue(cipher.length <= 7696, "密文长度最大支持7696"); KeyInfo keyInfo = checkKey(req.getKeyId(), KeyUsage.ENCRYPT_DECRYPT); KeyAlg keyAlg = KeyAlg.of(keyInfo.getKeyAlg()); Assert.notNull(keyAlg, "数据异常"); diff --git a/chsm-web-server/src/test/java/api/BaseTest.java b/chsm-web-server/src/test/java/api/BaseTest.java index 281e2c3..4b929b6 100644 --- a/chsm-web-server/src/test/java/api/BaseTest.java +++ b/chsm-web-server/src/test/java/api/BaseTest.java @@ -6,7 +6,9 @@ import com.fasterxml.jackson.databind.JsonNode; import com.sunyard.chsm.model.R; import com.sunyard.chsm.param.AppTokenReq; import com.sunyard.chsm.param.AppTokenResp; +import com.sunyard.chsm.utils.CodecUtils; import com.sunyard.chsm.utils.JsonUtils; +import com.sunyard.chsm.utils.gm.BCSM3Utils; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.MediaType; @@ -27,17 +29,18 @@ public abstract class BaseTest { protected static final String keyTemplate = "sym-sm4-001"; protected static final String ak = "216205d408130d83d13c5072305b8b65"; protected static final String sk = "ae64515d1d5adec2cc6ae8726d0c1bbc"; - protected static final String server = "http://172.16.18.46:8900"; + protected static final String server = "http://127.0.0.1:8900"; protected static final RestTemplate restTemplate; protected static final String token; static { AppTokenReq req = new AppTokenReq(); req.setAppKey(ak); - req.setHmac(sk); - req.setRandom(System.currentTimeMillis()); + req.setTimestamp(System.currentTimeMillis()); + byte[] hmac = BCSM3Utils.hmac(sk.getBytes(), (ak + req.getTimestamp() + sk).getBytes()); + req.setHmac(CodecUtils.encodeBase64(hmac)); - RequestEntity request = RequestEntity.post(server + "/appUser/getAppTokenTest") + RequestEntity request = RequestEntity.post(server + "/appUser/getAppToken") .contentType(MediaType.APPLICATION_JSON) .body(JsonUtils.toJsonBytes(req)); ResponseEntity response = new RestTemplate().exchange(request, String.class); @@ -70,7 +73,7 @@ public abstract class BaseTest { } JsonNode result = jsonNode.get("result"); if (result == null) { - return null; + return null; } JsonParser returnJsonParser = JsonUtils.objectMapper().treeAsTokens(result); return JsonUtils.objectMapper().readValue(returnJsonParser, tClass); diff --git a/chsm-web-server/src/test/java/api/HashTest.java b/chsm-web-server/src/test/java/api/HashTest.java new file mode 100644 index 0000000..f24397d --- /dev/null +++ b/chsm-web-server/src/test/java/api/HashTest.java @@ -0,0 +1,62 @@ +package api; + +import com.sunyard.chsm.param.HashReq; +import com.sunyard.chsm.param.HashResp; +import com.sunyard.chsm.sdf.util.LangUtils; +import com.sunyard.chsm.utils.CodecUtils; +import com.sunyard.chsm.utils.gm.BCSM3Utils; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +/** + * @author liulu + * @since 2024/12/25 + */ +@Slf4j +public class HashTest extends BaseTest { + + private static final byte[] plain = new byte[1024 * 7]; + + static { + Arrays.fill(plain, (byte) 0x04); + } + + + @Test + public void testSingleHash() { + HashReq hashReq = new HashReq(); + hashReq.setPlainData(CodecUtils.encodeBase64(plain)); + HashResp hashResp = execute("/hash", hashReq, HashResp.class); + log.info("hash: {}", hashResp.getHash()); + + byte[] bcHash = BCSM3Utils.hash(plain); + log.info("bc hash: {}", CodecUtils.encodeBase64(bcHash)); + Assertions.assertEquals(CodecUtils.encodeBase64(bcHash), hashResp.getHash()); + } + + @Test + public void testMultiHash() { + HashReq hashReq = new HashReq(); + HashResp hashResp = execute("/multi/package/hash/init", hashReq, HashResp.class); + log.info("hash: {}", hashResp); + + hashReq.setPlainData(CodecUtils.encodeBase64(plain)); + hashReq.setHandle(hashResp.getHandle()); + for (int i = 0; i < 2; i++) { + hashResp = execute("/multi/package/hash/update", hashReq, HashResp.class); + } + + hashResp = execute("/multi/package/hash/finish", hashReq, HashResp.class); + log.info("hash: {}", hashResp); + + + byte[] bcHash = BCSM3Utils.hash(LangUtils.merge(plain, plain)); + log.info("bc hash: {}", CodecUtils.encodeBase64(bcHash)); + Assertions.assertEquals(CodecUtils.encodeBase64(bcHash), hashResp.getHash()); + } + + +} diff --git a/chsm-web-server/src/test/java/api/SymKeyTest.java b/chsm-web-server/src/test/java/api/SymKeyTest.java index fae573b..150c8b7 100644 --- a/chsm-web-server/src/test/java/api/SymKeyTest.java +++ b/chsm-web-server/src/test/java/api/SymKeyTest.java @@ -1,12 +1,7 @@ package api; import com.sunyard.chsm.enums.AlgMode; -import com.sunyard.chsm.param.KeyCreateReq; -import com.sunyard.chsm.param.KeyManageReq; -import com.sunyard.chsm.param.SymDecryptReq; -import com.sunyard.chsm.param.SymDecryptResp; -import com.sunyard.chsm.param.SymEncryptReq; -import com.sunyard.chsm.param.SymEncryptResp; +import com.sunyard.chsm.param.*; import com.sunyard.chsm.utils.CodecUtils; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterAll; @@ -15,6 +10,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.util.StringUtils; +import java.util.Arrays; import java.util.Collections; /** @@ -24,12 +20,13 @@ import java.util.Collections; @Slf4j public class SymKeyTest extends BaseTest { - private static final String plain = "hjsu234127qikqwndqqw13412as324"; + private static final byte[] plain = new byte[1024 * 7]; private final static byte[] iv = "ghwikdhj1234713v".getBytes(); private static Long keyId; @BeforeAll public static void beforeAll() { + Arrays.fill(plain, (byte) 0x04); keyId = execute("/key/gen", KeyCreateReq.builder().keyTemplateCode(keyTemplate).genNumber(1).build(), Long.class); Assertions.assertTrue(keyId > 0); } @@ -47,7 +44,7 @@ public class SymKeyTest extends BaseTest { SymEncryptReq symEncryptReq = new SymEncryptReq(); symEncryptReq.setKeyId(keyId); - symEncryptReq.setPlainData(CodecUtils.encodeBase64(plain.getBytes())); + symEncryptReq.setPlainData(CodecUtils.encodeBase64(plain)); symEncryptReq.setIv(CodecUtils.encodeBase64(iv)); symEncryptReq.setMode(AlgMode.CBC); @@ -56,7 +53,7 @@ public class SymKeyTest extends BaseTest { Assertions.assertNotNull(symEncryptResp); Assertions.assertTrue(StringUtils.hasText(symEncryptResp.getKeyIndex())); byte[] cipherData = CodecUtils.decodeBase64(symEncryptResp.getCipherData()); - Assertions.assertEquals(32, cipherData.length); +// Assertions.assertEquals(32, cipherData.length); SymDecryptReq decryptReq = new SymDecryptReq(); decryptReq.setKeyId(keyId); @@ -65,10 +62,10 @@ public class SymKeyTest extends BaseTest { decryptReq.setMode(AlgMode.CBC); decryptReq.setCipherData(symEncryptResp.getCipherData()); SymDecryptResp decryptResp = execute("/sym/decrypt", decryptReq, SymDecryptResp.class); - String calPlain = new String(CodecUtils.decodeBase64(decryptResp.getPlainData())); + byte[] calPlain = CodecUtils.decodeBase64(decryptResp.getPlainData()); log.info("SymDecryptResp: {}, {}", calPlain, decryptResp); Assertions.assertNotNull(decryptResp); - Assertions.assertEquals(plain, calPlain); + Assertions.assertArrayEquals(plain, calPlain); }