diff --git a/pom.xml b/pom.xml
index d85b796..ef7d946 100644
--- a/pom.xml
+++ b/pom.xml
@@ -115,6 +115,13 @@
commons-csv
1.10.0
+
+
+ com.sunyard.cisd
+ device-fingerprint-tool
+ 1.0.0
+
+
diff --git a/src/main/java/com/cisd/tms/modules/device/controller/NetworkConfigController.java b/src/main/java/com/cisd/tms/modules/device/controller/NetworkConfigController.java
index f0fae4c..e0d2964 100644
--- a/src/main/java/com/cisd/tms/modules/device/controller/NetworkConfigController.java
+++ b/src/main/java/com/cisd/tms/modules/device/controller/NetworkConfigController.java
@@ -29,7 +29,6 @@ public class NetworkConfigController {
@Operation(summary = "获取所有网卡名", description = "获取系统中所有网卡名称")
@GetMapping("/card/eth-names")
- @AuditedOperation(module = ModuleCode.DEVICE, action = ActionType.CREATE, summary = "获取所有网卡名")
public ApiResponse> getEthDeviceNames() {
return ApiResponse.success(networkConfigService.getEthDeviceNames());
}
diff --git a/src/main/java/com/cisd/tms/modules/mk/config/MasterKeyActivateProperties.java b/src/main/java/com/cisd/tms/modules/mk/config/MasterKeyActivateProperties.java
new file mode 100644
index 0000000..e14a10a
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/config/MasterKeyActivateProperties.java
@@ -0,0 +1,15 @@
+package com.cisd.tms.modules.mk.config;
+
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "tms.mk.activate")
+public class MasterKeyActivateProperties {
+
+ //todo 后续添加到配置文件
+ private String activateUrl = "http://127.0.0.1:8080/device/activate";
+
+ public String getActivateUrl() { return activateUrl; }
+
+ public void setActivateUrl(String activateUrl) { this.activateUrl = activateUrl; }
+}
diff --git a/src/main/java/com/cisd/tms/modules/mk/controller/LmkController.java b/src/main/java/com/cisd/tms/modules/mk/controller/LmkController.java
index 1c5f996..2231373 100644
--- a/src/main/java/com/cisd/tms/modules/mk/controller/LmkController.java
+++ b/src/main/java/com/cisd/tms/modules/mk/controller/LmkController.java
@@ -6,12 +6,9 @@ import com.cisd.tms.common.exception.BizException;
import com.cisd.tms.modules.auth.enums.AuthLevel;
import com.cisd.tms.modules.auth.enums.RoleCode;
import com.cisd.tms.modules.auth.security.RequireInternalAuth;
-import com.cisd.tms.modules.mk.dto.MasterKeyBackupPacket;
-import com.cisd.tms.modules.mk.dto.MasterKeyRecoverRequest;
-import com.cisd.tms.modules.mk.dto.MasterKeyRecoverPacketsRequest;
-import com.cisd.tms.modules.mk.dto.MasterKeyStateResult;
-import com.cisd.tms.modules.mk.enums.MasterKeyStatus;
+import com.cisd.tms.modules.mk.dto.*;
import com.cisd.tms.modules.mk.service.LmkService;
+import com.cisd.tms.modules.mk.service.MasterKeyActivateService;
import com.cisd.tms.security.internal.ReplayProtected;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -34,6 +31,7 @@ import java.util.List;
public class LmkController {
private final LmkService lmkService;
+ private final MasterKeyActivateService masterKeyActivateService;
@PostMapping("/masterKey/init")
@Operation(summary = "初始化主密钥", description = "执行密码卡初始化识别、主密钥生成加载、内部密钥生成,并返回主密钥状态与校验值。")
@@ -70,6 +68,21 @@ public class LmkController {
return ApiResponse.success();
}
+
+ @PostMapping("/masterKey/activate")
+ @Operation(summary = "设备激活")
+ public ApiResponse Activate(@RequestBody MasterKeyActivateRequest masterKeyActivateRequest) {
+ masterKeyActivateService.activate(masterKeyActivateRequest);
+ return ApiResponse.success();
+ }
+
+
+ @GetMapping("/masterKey/activate/info")
+ @Operation(summary = "查询设备激活信息", description = "返回设备型号、设备名称、设备序列号、设备版本、设备状态、异常原因。")
+ public ApiResponse getMasterKeyActivateInfo() {
+ return ApiResponse.success(masterKeyActivateService.getMasterKeyActivateInfo());
+ }
+
private void validatePacketIndexes(List packets) {
if (packets == null || packets.size() != 2) {
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "packets数量必须为2");
diff --git a/src/main/java/com/cisd/tms/modules/mk/dto/MasterKeyActivateInfoResponse.java b/src/main/java/com/cisd/tms/modules/mk/dto/MasterKeyActivateInfoResponse.java
new file mode 100644
index 0000000..2896b27
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/dto/MasterKeyActivateInfoResponse.java
@@ -0,0 +1,22 @@
+package com.cisd.tms.modules.mk.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(description = "设备激活信息响应")
+public class MasterKeyActivateInfoResponse {
+
+ @Schema(description = "设备型号", example = "SYD7108")
+ private String deviceModel;
+ @Schema(description = "设备名称", example = "跨境支付终端一体机")
+ private String deviceName;
+ @Schema(description = "设备版本", example = "1.0.0")
+ private String version;
+ @Schema(description = "设备序列号", example = "1234567890ABCDEF")
+ private String serialNumber;
+ @Schema(description = "设备状态:normal/abnormal", example = "normal")
+ private String deviceStatus;
+ @Schema(description = "异常原因")
+ private String exceptionMessage;
+}
diff --git a/src/main/java/com/cisd/tms/modules/mk/dto/MasterKeyActivateRequest.java b/src/main/java/com/cisd/tms/modules/mk/dto/MasterKeyActivateRequest.java
new file mode 100644
index 0000000..0047f01
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/dto/MasterKeyActivateRequest.java
@@ -0,0 +1,16 @@
+package com.cisd.tms.modules.mk.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(description = "设备激活请求")
+public class MasterKeyActivateRequest {
+
+ @Schema(description = "使用者ID", example = "1234567")
+ private String userId;
+ @Schema(description = "身份凭证", example = "1234567")
+ private String credential;
+ @Schema(description = "设备激活码", example = "1234567")
+ private String activationCode;
+}
diff --git a/src/main/java/com/cisd/tms/modules/mk/entity/MasterKeyActivateEntity.java b/src/main/java/com/cisd/tms/modules/mk/entity/MasterKeyActivateEntity.java
new file mode 100644
index 0000000..65c4739
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/entity/MasterKeyActivateEntity.java
@@ -0,0 +1,26 @@
+package com.cisd.tms.modules.mk.entity;
+
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("tms_master_key_activate")
+public class MasterKeyActivateEntity {
+
+ private Long id;
+
+ private Boolean everInitialized;
+
+ private Boolean activationStatus;
+
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/cisd/tms/modules/mk/mapper/MasterKeyActivateMapper.java b/src/main/java/com/cisd/tms/modules/mk/mapper/MasterKeyActivateMapper.java
new file mode 100644
index 0000000..1b1ec12
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/mapper/MasterKeyActivateMapper.java
@@ -0,0 +1,9 @@
+package com.cisd.tms.modules.mk.mapper;
+
+import com.cisd.tms.infrastructure.persistence.mapper.BaseMapperX;
+import com.cisd.tms.modules.mk.entity.MasterKeyActivateEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface MasterKeyActivateMapper extends BaseMapperX {
+}
diff --git a/src/main/java/com/cisd/tms/modules/mk/repository/MasterKeyActivateRepository.java b/src/main/java/com/cisd/tms/modules/mk/repository/MasterKeyActivateRepository.java
new file mode 100644
index 0000000..5fafbdd
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/repository/MasterKeyActivateRepository.java
@@ -0,0 +1,10 @@
+package com.cisd.tms.modules.mk.repository;
+
+import com.cisd.tms.modules.mk.entity.MasterKeyActivateEntity;
+
+import java.util.Optional;
+
+public interface MasterKeyActivateRepository {
+ Optional find();
+ void update(MasterKeyActivateEntity masterKeyActivateEntity);
+}
diff --git a/src/main/java/com/cisd/tms/modules/mk/repository/impl/MasterKeyActivateRepositoryImpl.java b/src/main/java/com/cisd/tms/modules/mk/repository/impl/MasterKeyActivateRepositoryImpl.java
new file mode 100644
index 0000000..46116b6
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/repository/impl/MasterKeyActivateRepositoryImpl.java
@@ -0,0 +1,53 @@
+package com.cisd.tms.modules.mk.repository.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.cisd.tms.modules.mk.entity.MasterKeyActivateEntity;
+import com.cisd.tms.modules.mk.mapper.MasterKeyActivateMapper;
+import com.cisd.tms.modules.mk.repository.MasterKeyActivateRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public class MasterKeyActivateRepositoryImpl implements MasterKeyActivateRepository {
+
+ private final MasterKeyActivateMapper masterKeyActivateMapper;
+ public MasterKeyActivateRepositoryImpl(MasterKeyActivateMapper masterKeyActivateMapper) {
+ this.masterKeyActivateMapper = masterKeyActivateMapper;
+ }
+
+ @Override
+ public Optional find() {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+
+ wrapper.last("LIMIT 1");
+
+ MasterKeyActivateEntity entity = masterKeyActivateMapper.selectOne(wrapper);
+ return Optional.ofNullable(entity);
+ }
+
+ @Override
+ public void update(MasterKeyActivateEntity masterKeyActivateEntity) {
+// LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+//
+// wrapper.last("LIMIT 1");
+//
+// MasterKeyActivateEntity entity = masterKeyActivateMapper.selectOne(wrapper);
+//
+// entity.setEverInitialized(everInitialized);
+ masterKeyActivateMapper.updateById(masterKeyActivateEntity);
+ }
+
+
+// @Override
+// public void updateActivateStatus(Boolean activateStatus) {
+// LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+//
+// wrapper.last("LIMIT 1");
+//
+// MasterKeyActivateEntity entity = masterKeyActivateMapper.selectOne(wrapper);
+//
+// entity.setEverInitialized(activateStatus);
+// masterKeyActivateMapper.updateById(entity);
+// }
+}
diff --git a/src/main/java/com/cisd/tms/modules/mk/service/MasterKeyActivateService.java b/src/main/java/com/cisd/tms/modules/mk/service/MasterKeyActivateService.java
new file mode 100644
index 0000000..f129123
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/service/MasterKeyActivateService.java
@@ -0,0 +1,11 @@
+package com.cisd.tms.modules.mk.service;
+
+import com.cisd.tms.modules.mk.dto.MasterKeyActivateInfoResponse;
+import com.cisd.tms.modules.mk.dto.MasterKeyActivateRequest;
+
+public interface MasterKeyActivateService {
+
+ void activate(MasterKeyActivateRequest masterKeyActivateRequest);
+
+ MasterKeyActivateInfoResponse getMasterKeyActivateInfo();
+}
diff --git a/src/main/java/com/cisd/tms/modules/mk/service/impl/LmkServiceImpl.java b/src/main/java/com/cisd/tms/modules/mk/service/impl/LmkServiceImpl.java
index c642f46..1a6ebc8 100644
--- a/src/main/java/com/cisd/tms/modules/mk/service/impl/LmkServiceImpl.java
+++ b/src/main/java/com/cisd/tms/modules/mk/service/impl/LmkServiceImpl.java
@@ -4,39 +4,26 @@ import com.cisd.tms.common.enums.ErrorCode;
import com.cisd.tms.common.exception.BizException;
import com.cisd.tms.common.util.DivisionUtils;
import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds;
-import com.cisd.tms.integration.crypto.pcie.PcieUserKeyType;
import com.cisd.tms.integration.crypto.pcie.jna.EccRefPublicKey;
-import com.cisd.tms.integration.crypto.pcie.jna.EccSignature;
import com.cisd.tms.integration.crypto.pcie.model.*;
import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
import com.cisd.tms.modules.auth.service.AuthSecurityResetService;
import com.cisd.tms.modules.mk.common.LMKConstant;
import com.cisd.tms.modules.mk.config.MasterKeyInitProperties;
-import com.cisd.tms.modules.mk.dto.MasterKeyBackupMaterial;
-import com.cisd.tms.modules.mk.dto.MasterKeyBackupPacket;
-import com.cisd.tms.modules.mk.dto.MasterKeyPacketIkPart;
-import com.cisd.tms.modules.mk.dto.MasterKeyPacketLmkPart;
-import com.cisd.tms.modules.mk.dto.MasterKeyPacketUserKeyPart;
-import com.cisd.tms.modules.mk.dto.MasterKeyStateResult;
+import com.cisd.tms.modules.mk.dto.*;
+import com.cisd.tms.modules.mk.entity.MasterKeyActivateEntity;
import com.cisd.tms.modules.mk.enums.IKEnums;
import com.cisd.tms.modules.mk.enums.MasterKeyStatus;
+import com.cisd.tms.modules.mk.repository.MasterKeyActivateRepository;
import com.cisd.tms.modules.mk.service.LmkService;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
/**
* 主密钥生命周期服务实现。
*/
@@ -70,20 +57,23 @@ public class LmkServiceImpl implements LmkService {
private final AuthSecurityResetService authSecurityResetService;
private final Object backupRoundLock = new Object();
private CachedBackupRound cachedBackupRound;
+ private final MasterKeyActivateRepository masterKeyActivateRepository;
@Autowired
public LmkServiceImpl(
PcieCryptoService pcieCryptoService,
MasterKeyInitProperties masterKeyInitProperties,
- AuthSecurityResetService authSecurityResetService
+ AuthSecurityResetService authSecurityResetService,
+ MasterKeyActivateRepository masterKeyActivateRepository
) {
this.pcieCryptoService = pcieCryptoService;
this.masterKeyInitProperties = masterKeyInitProperties;
this.authSecurityResetService = authSecurityResetService;
+ this.masterKeyActivateRepository = masterKeyActivateRepository;
}
- public LmkServiceImpl(PcieCryptoService pcieCryptoService, MasterKeyInitProperties masterKeyInitProperties) {
- this(pcieCryptoService, masterKeyInitProperties, () -> { });
+ public LmkServiceImpl(PcieCryptoService pcieCryptoService, MasterKeyInitProperties masterKeyInitProperties, MasterKeyActivateRepository masterKeyActivateRepository) {
+ this(pcieCryptoService, masterKeyInitProperties, () -> { }, masterKeyActivateRepository);
}
@Override
@@ -91,6 +81,17 @@ public class LmkServiceImpl implements LmkService {
if (pcieCryptoService.checkLmk()) {
throw new BizException(ErrorCode.CONFLICT.getCode(), "主密钥已存在,拒绝重新初始化");
}
+
+ MasterKeyActivateEntity masterKeyActivateEntity = masterKeyActivateRepository.find().
+ orElseThrow(() -> new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "激活记录不存在"));
+ boolean everInitialized = masterKeyActivateEntity.getEverInitialized();
+ boolean activationStatus = masterKeyActivateEntity.getActivationStatus();
+ if (!everInitialized) {
+ if (!activationStatus) {
+ throw new BizException(ErrorCode.FORBIDDEN.getCode(), "需要先进行激活");
+ }
+ }
+
// 密钥体系一旦重建,之前导出的两份备份包就全部失效,必须清空当前轮次缓存。
clearCachedBackupRound();
byte[] oldPin = decodeConfiguredPin("tms.mk.init-identify.old-pin-base64", masterKeyInitProperties.getOldPinBase64());
@@ -100,6 +101,10 @@ public class LmkServiceImpl implements LmkService {
result.setStatus(true);
result.setSeedMac(Hex.toHexString(pcieCryptoService.initializeMasterKey(oldPin, newPin)));
authSecurityResetService.resetAfterMasterKeyInitialized();
+
+ masterKeyActivateEntity.setActivationStatus(false);
+ masterKeyActivateEntity.setEverInitialized(false);
+ masterKeyActivateRepository.update(masterKeyActivateEntity);
return result;
}
diff --git a/src/main/java/com/cisd/tms/modules/mk/service/impl/MasterKeyActivateServiceImpl.java b/src/main/java/com/cisd/tms/modules/mk/service/impl/MasterKeyActivateServiceImpl.java
new file mode 100644
index 0000000..755aa26
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/mk/service/impl/MasterKeyActivateServiceImpl.java
@@ -0,0 +1,385 @@
+package com.cisd.tms.modules.mk.service.impl;
+
+import com.cisd.tms.common.enums.ErrorCode;
+import com.cisd.tms.common.exception.BizException;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
+import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
+import com.cisd.tms.modules.device.config.DeviceProfileProperties;
+import com.cisd.tms.modules.device.dto.DeviceInfoResponse;
+import com.cisd.tms.modules.device.entity.DeviceSoftwareVersionEntity;
+import com.cisd.tms.modules.device.repository.DeviceSoftwareVersionRepository;
+import com.cisd.tms.modules.device.service.DeviceService;
+import com.cisd.tms.modules.mk.config.MasterKeyActivateProperties;
+import com.cisd.tms.modules.mk.dto.MasterKeyActivateInfoResponse;
+import com.cisd.tms.modules.mk.dto.MasterKeyActivateRequest;
+import com.cisd.tms.modules.mk.entity.MasterKeyActivateEntity;
+import com.cisd.tms.modules.mk.repository.MasterKeyActivateRepository;
+import com.cisd.tms.modules.mk.service.MasterKeyActivateService;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.sunyard.cisd.DeviceFingerprint;
+import com.sunyard.cisd.DeviceFingerprintService;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+import org.bouncycastle.crypto.CipherParameters;
+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.params.ParametersWithRandom;
+import org.bouncycastle.crypto.signers.SM2Signer;
+import org.bouncycastle.jce.ECNamedCurveTable;
+import org.bouncycastle.jce.interfaces.ECPrivateKey;
+import org.bouncycastle.jce.interfaces.ECPublicKey;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.springframework.stereotype.Service;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.util.Base64;
+import java.util.Optional;
+
+@Service
+@RequiredArgsConstructor
+public class MasterKeyActivateServiceImpl implements MasterKeyActivateService {
+
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+ private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+
+ private final PcieCryptoService pcieCryptoService;
+ private final MasterKeyActivateProperties masterKeyActivateProperties;
+ private final DeviceSoftwareVersionRepository deviceSoftwareVersionRepository;
+ private final DeviceProfileProperties deviceProfileProperties;
+ private final DeviceService deviceService;
+ private final MasterKeyActivateRepository masterKeyActivateRepository;
+
+ static {
+ if (Security.getProvider("BC") == null) {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+ }
+
+ @Override
+ public MasterKeyActivateInfoResponse getMasterKeyActivateInfo() {
+ DeviceInfoResponse deviceInfoResponse = deviceService.info();
+ DeviceInfoResult deviceInfo = pcieCryptoService.getDeviceInfo();
+
+ MasterKeyActivateInfoResponse masterKeyActivateInfo = new MasterKeyActivateInfoResponse();
+
+ if (deviceInfoResponse.getMasterKeyStatus()) {
+ masterKeyActivateInfo.setDeviceStatus("正常");
+ } else {
+ masterKeyActivateInfo.setDeviceStatus("异常");
+ masterKeyActivateInfo.setExceptionMessage("密钥异常");
+ }
+
+ if (deviceInfo == null){
+ masterKeyActivateInfo.setSerialNumber("");
+ } else {
+ masterKeyActivateInfo.setSerialNumber(deviceInfo.getDeviceSerial());
+ }
+ masterKeyActivateInfo.setDeviceModel(trim(deviceProfileProperties.getModel()));
+ masterKeyActivateInfo.setDeviceName(trim(deviceProfileProperties.getName()));
+ masterKeyActivateInfo.setVersion(loadTmsVersion());
+ return masterKeyActivateInfo;
+ }
+
+
+
+
+ @Override
+ public void activate(MasterKeyActivateRequest masterKeyActivateRequest){
+ MasterKeyActivateEntity masterKeyActivateEntity = masterKeyActivateRepository.find().orElseThrow(() -> new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "激活记录不存在"));
+
+ Boolean everInitialized = masterKeyActivateEntity.getEverInitialized();
+ if (everInitialized) {
+ throw new BizException(ErrorCode.BIZ_ERROR.getCode(), "从未进行初始化密钥, 无需激活");
+ }
+
+ if (masterKeyActivateRequest.getUserId() == null){
+ throw new IllegalArgumentException("使用者ID不能为空");
+ }
+
+ if (masterKeyActivateRequest.getCredential() == null){
+ throw new IllegalArgumentException("身份凭证不能为空");
+ }
+
+ if (masterKeyActivateRequest.getActivationCode() == null){
+ throw new IllegalArgumentException("设备激活码不能为空");
+ }
+
+ try {
+ DeviceFingerprintService deviceFingerprintService = new DeviceFingerprintService();
+ DeviceFingerprint deviceFingerprint = deviceFingerprintService.getDeviceFingerprint();
+
+ String deviceSerial = deviceFingerprint.getDeviceSerialNumber();
+ String motherboardSerial = deviceFingerprint.getMotherboardSerialNumber();
+ String cpuModel = deviceFingerprint.getCpuModel();
+ String cpuSerial = deviceFingerprint.getCpuSerialNumber();
+ String memorySize = deviceFingerprint.getMemorySize();
+ String macAddress = deviceFingerprint.getFirstNetworkMacAddress();
+ String diskSerial = deviceFingerprint.getHardDiskSerialNumber();
+
+ String timestamp = String.valueOf(System.currentTimeMillis());
+
+ String nonce = randomHex(16);
+
+ //todo 后面读取文件
+ MasterKeyActivateServiceImpl.Sm2KeyPair sm2KeyPair = generateSm2KeyPair();
+
+ String deviceFingerprintSource =
+ deviceSerial +
+ motherboardSerial +
+ cpuModel +
+ cpuSerial +
+ memorySize +
+ macAddress +
+ diskSerial;
+
+ String deviceFingerprintSm2 = sm2SignBase64(
+ deviceFingerprintSource.getBytes(StandardCharsets.UTF_8),
+ sm2KeyPair.privateKey
+ );
+
+
+ String userId = trim(masterKeyActivateRequest.getUserId());
+ String credential = trim(masterKeyActivateRequest.getCredential());
+ String activationCode = trim(masterKeyActivateRequest.getActivationCode());
+
+
+
+
+ String hashSource = userId + credential + activationCode + deviceSerial +
+ deviceFingerprint + timestamp + nonce;
+ String hash = sm3Hex(hashSource);
+
+ Params params = new Params();
+ params.userId = userId;
+ params.credential = credential;
+ params.activationCode = activationCode;
+ params.deviceSerial = deviceSerial;
+ params.deviceFingerprint = deviceFingerprintSm2;
+ params.timestamp = timestamp;
+ params.nonce = nonce;
+
+ ActivateRequest request = new ActivateRequest();
+ request.params = params;
+ request.hash = hash;
+
+ //todo 先写死后续改实际的激活服务
+ masterKeyActivateEntity.setActivationStatus(true);
+ masterKeyActivateRepository.update(masterKeyActivateEntity);
+// String json = OBJECT_MAPPER.writeValueAsString(request);
+//// System.out.print(json);
+// HttpRequest httpRequest = HttpRequest.newBuilder()
+// .uri(URI.create(masterKeyActivateProperties.getActivateUrl()))
+// .header("Content-Type", "application/json;charset=UTF-8")
+// .header("Accept", "application/json")
+// .POST(HttpRequest.BodyPublishers.ofString(json, StandardCharsets.UTF_8))
+// .build();
+//
+// HttpClient client = HttpClient.newHttpClient();
+//
+// HttpResponse response = client.send(
+// httpRequest,
+// HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
+// );
+//
+// ServerResponse result =
+// OBJECT_MAPPER.readValue(response.body(), ServerResponse.class);
+//
+// if ("ok".equals(result.status)) {
+// MasterKeyActivateData dataResponse = result.getData();
+// String inputHash = dataResponse.getInputHash();
+// String deviceActivationPublicKey = dataResponse.getDeviceActivationPublicKey();
+// String activationResult = dataResponse.getActivationResult();
+//
+// } else {
+// throw new Exception(result.getMsg());
+// }
+
+ } catch (Exception e) {
+ masterKeyActivateEntity.setActivationStatus(false);
+ masterKeyActivateRepository.update(masterKeyActivateEntity);
+ throw new BizException(ErrorCode.BIZ_ERROR.getCode(), "激活失败:" + e.getMessage());
+ }
+ }
+
+
+
+
+ private String sm2SignBase64(
+ byte[] data,
+ ECPrivateKeyParameters privateKey
+ ) throws Exception {
+
+ SM2Signer signer = new SM2Signer(new SM3Digest());
+
+ CipherParameters parameters = new ParametersWithRandom(privateKey, SECURE_RANDOM);
+
+ signer.init(true, parameters);
+ signer.update(data, 0, data.length);
+
+ byte[] signature = signer.generateSignature();
+
+ return Base64.getEncoder().encodeToString(signature);
+ }
+
+
+ private Sm2KeyPair generateSm2KeyPair(){
+ try{
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
+ ECParameterSpec sm2Spec = ECNamedCurveTable.getParameterSpec("sm2p256v1");
+ keyPairGenerator.initialize(sm2Spec, SECURE_RANDOM);
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+ ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
+ ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
+ BigInteger d = privateKey.getD();
+
+ ECDomainParameters domainParameters = new ECDomainParameters(
+ sm2Spec.getCurve(),
+ sm2Spec.getG(),
+ sm2Spec.getN(),
+ sm2Spec.getH()
+ );
+
+ ECPrivateKeyParameters privateKeyParameters =
+ new ECPrivateKeyParameters(d, domainParameters);
+
+ ECPublicKeyParameters publicParameters =
+ new ECPublicKeyParameters(publicKey.getQ(), domainParameters);
+
+
+ Sm2KeyPair sm2KeyPair = new Sm2KeyPair();
+ sm2KeyPair.privateKey = privateKeyParameters;
+ sm2KeyPair.publicKeyParameters = publicParameters;
+ sm2KeyPair.publicKey = publicKey;
+
+ return sm2KeyPair;
+ } catch (Exception e){
+ throw new BizException(ErrorCode.BIZ_ERROR.getCode(), "sm2密钥对生成失败");
+ }
+
+ }
+
+ private String sm3Hex(String input) {
+ byte[] data = input.getBytes(StandardCharsets.UTF_8);
+
+ SM3Digest digest = new SM3Digest();
+ digest.update(data, 0, data.length);
+
+ byte[] result = new byte[digest.getDigestSize()];
+ digest.doFinal(result, 0);
+
+ return bytesToHex(result);
+ }
+
+ private String randomHex(int byteLength) {
+ byte[] bytes = new byte[byteLength];
+ SECURE_RANDOM.nextBytes(bytes);
+ return bytesToHex(bytes);
+ }
+
+ private String bytesToHex(byte[] bytes) {
+ StringBuilder sb = new StringBuilder(bytes.length * 2);
+
+ for (byte b : bytes) {
+ sb.append(String.format("%02x", b & 0xff));
+ }
+
+ return sb.toString();
+ }
+
+
+ private boolean sm2VerifyActivationResult(
+ String inputHash,
+ String activationResult,
+ ECPublicKeyParameters publicKeyParameters
+ ) {
+ try {
+
+ byte[] signatureBytes = parseP1Signature(activationResult);
+
+ SM2Signer signer = new SM2Signer(new SM3Digest());
+
+
+ signer.init(false, publicKeyParameters);
+
+ byte[] data = inputHash.getBytes(StandardCharsets.UTF_8);
+
+ signer.update(data, 0, data.length);
+
+ return signer.verifySignature(signatureBytes);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ private byte[] parseP1Signature(String activationResult) {
+ String value = activationResult.trim();
+ if (value.startsWith("P1:")) {
+ value = value.substring(3);
+ }
+ return Base64.getDecoder().decode(value);
+ }
+
+ public static class ActivateRequest {
+
+ public Params params;
+ public String hash;
+ }
+
+ public static class Params {
+
+ public String userId;
+ public String credential;
+ public String activationCode;
+ public String deviceSerial;
+ public String deviceFingerprint;
+ public String timestamp;
+ public String nonce;
+ }
+
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ @Data
+ public static class ServerResponse {
+ public String status;
+ public String msg;
+ public Integer code;
+ public MasterKeyActivateData data;
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ @Data
+ public static class MasterKeyActivateData {
+
+ public String inputHash;
+ public String deviceActivationPublicKey;
+ public String activationResult;
+ }
+
+ private static class Sm2KeyPair {
+ private ECPrivateKeyParameters privateKey;
+ private ECPublicKeyParameters publicKeyParameters;
+ private ECPublicKey publicKey;
+ }
+
+ private String loadTmsVersion() {
+ Optional version = deviceSoftwareVersionRepository.findByComponentCode("TMS");
+ return version.map(DeviceSoftwareVersionEntity::getCurrentVersion).map(MasterKeyActivateServiceImpl::trim).orElse("");
+ }
+
+ private static String trim(String value) {
+ return value == null ? "" : value.trim();
+ }
+}
diff --git a/src/main/resources/db/migration/V1__tms_schema_full.sql b/src/main/resources/db/migration/V1__tms_schema_full.sql
index 920b71f..51a31a5 100644
--- a/src/main/resources/db/migration/V1__tms_schema_full.sql
+++ b/src/main/resources/db/migration/V1__tms_schema_full.sql
@@ -714,3 +714,20 @@ CREATE TABLE IF NOT EXISTS tms_backup_config (
sign_data varchar(255) NOT NULL COMMENT '其他字段的签名值',
PRIMARY KEY (`id`)
)
+
+
+CREATE TABLE tms_master_key_activate (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+
+ ever_initialized BOOLEAN NOT NULL,
+
+ activation_status BOOLEAN NOT NULL,
+
+ create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
+ update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)
+);
+
+INSERT INTO tms_master_key_activate (
+ ever_initialized,
+ activation_status
+) VALUES (true,false);
diff --git a/src/test/java/com/cisd/tms/modules/mk/controller/LmkControllerTest.java b/src/test/java/com/cisd/tms/modules/mk/controller/LmkControllerTest.java
index c0b7fc5..def9f3e 100644
--- a/src/test/java/com/cisd/tms/modules/mk/controller/LmkControllerTest.java
+++ b/src/test/java/com/cisd/tms/modules/mk/controller/LmkControllerTest.java
@@ -3,6 +3,7 @@ package com.cisd.tms.modules.mk.controller;
import com.cisd.tms.common.exception.GlobalExceptionHandler;
import com.cisd.tms.modules.mk.dto.MasterKeyStateResult;
import com.cisd.tms.modules.mk.service.LmkService;
+import com.cisd.tms.modules.mk.service.MasterKeyActivateService;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.http.MediaType;
@@ -18,11 +19,12 @@ class LmkControllerTest {
@Test
void shouldReturnRecoveredMasterKeySeedMac() throws Exception {
LmkService lmkService = Mockito.mock(LmkService.class);
+ MasterKeyActivateService masterKeyActivateService = Mockito.mock(MasterKeyActivateService.class);
MasterKeyStateResult result = new MasterKeyStateResult();
result.setStatus(true);
result.setSeedMac("1112131415161718");
Mockito.when(lmkService.recoverKeyPackets(Mockito.any())).thenReturn(result);
- MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new LmkController(lmkService))
+ MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new LmkController(lmkService, masterKeyActivateService))
.setControllerAdvice(new GlobalExceptionHandler())
.build();
@@ -62,7 +64,8 @@ class LmkControllerTest {
@Test
void shouldRejectRecoverPacketsWithPacketIndexesOtherThanOneAndTwo() throws Exception {
LmkService lmkService = Mockito.mock(LmkService.class);
- MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new LmkController(lmkService))
+ MasterKeyActivateService masterKeyActivateService = Mockito.mock(MasterKeyActivateService.class);
+ MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new LmkController(lmkService, masterKeyActivateService))
.setControllerAdvice(new GlobalExceptionHandler())
.build();
diff --git a/src/test/java/com/cisd/tms/modules/mk/service/LmkServiceTest.java b/src/test/java/com/cisd/tms/modules/mk/service/LmkServiceTest.java
index 551dfe5..500c6cb 100644
--- a/src/test/java/com/cisd/tms/modules/mk/service/LmkServiceTest.java
+++ b/src/test/java/com/cisd/tms/modules/mk/service/LmkServiceTest.java
@@ -1,51 +1,41 @@
package com.cisd.tms.modules.mk.service;
+import com.cisd.tms.common.enums.ErrorCode;
+import com.cisd.tms.common.exception.BizException;
import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds;
import com.cisd.tms.integration.crypto.pcie.jna.EccRefPublicKey;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeIkComponent;
-import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
-import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
-import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
-import com.cisd.tms.integration.crypto.pcie.model.EccInternalSignRequest;
-import com.cisd.tms.integration.crypto.pcie.model.EccInternalVerifyRequest;
-import com.cisd.tms.integration.crypto.pcie.model.IkSignRequest;
-import com.cisd.tms.integration.crypto.pcie.model.IkVerifyRequest;
-import com.cisd.tms.integration.crypto.pcie.model.MasterKeyRecoveryRequest;
-import com.cisd.tms.integration.crypto.pcie.model.MasterKeyRecoveryResult;
-import com.cisd.tms.integration.crypto.pcie.model.RecoverUserKeyRequest;
+import com.cisd.tms.integration.crypto.pcie.model.*;
import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
-import com.cisd.tms.common.enums.ErrorCode;
-import com.cisd.tms.common.exception.BizException;
import com.cisd.tms.modules.auth.service.AuthSecurityResetService;
import com.cisd.tms.modules.mk.config.MasterKeyInitProperties;
-import com.cisd.tms.modules.mk.dto.MasterKeyBackupPacket;
-import com.cisd.tms.modules.mk.dto.MasterKeyPacketIkPart;
-import com.cisd.tms.modules.mk.dto.MasterKeyPacketLmkPart;
-import com.cisd.tms.modules.mk.dto.MasterKeyPacketUserKeyPart;
-import com.cisd.tms.modules.mk.dto.MasterKeyStateResult;
+import com.cisd.tms.modules.mk.dto.*;
+import com.cisd.tms.modules.mk.repository.MasterKeyActivateRepository;
import com.cisd.tms.modules.mk.service.impl.LmkServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mockito;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
class LmkServiceTest {
@Test
void shouldInitMasterKeyWithConfiguredPinsAndReturnSeedMac() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
Mockito.when(pcieCryptoService.initializeMasterKey(Mockito.any(), Mockito.any())).thenReturn(new byte[] {0x01, 0x23, 0x45, 0x67});
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
MasterKeyStateResult result = service.initMasterKey();
@@ -61,11 +51,12 @@ class LmkServiceTest {
@Test
void shouldResetAuthSecurityStateAfterMasterKeyInitializationSucceeds() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
AuthSecurityResetService authSecurityResetService = Mockito.mock(AuthSecurityResetService.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
Mockito.when(pcieCryptoService.initializeMasterKey(Mockito.any(), Mockito.any())).thenReturn(new byte[] {0x01, 0x23});
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties, authSecurityResetService);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, authSecurityResetService, masterKeyActivateRepository);
service.initMasterKey();
@@ -77,11 +68,12 @@ class LmkServiceTest {
@Test
void shouldPropagateInitMasterKeyFailure() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
Mockito.when(pcieCryptoService.initializeMasterKey(Mockito.any(), Mockito.any()))
.thenThrow(new IllegalStateException("主密钥初始化失败"));
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, service::initMasterKey);
@@ -91,10 +83,11 @@ class LmkServiceTest {
@Test
void shouldRejectInitMasterKeyWhenMasterKeyAlreadyExists() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
Mockito.when(pcieCryptoService.checkLmk()).thenReturn(true);
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
BizException exception = Assertions.assertThrows(BizException.class, service::initMasterKey);
@@ -106,8 +99,9 @@ class LmkServiceTest {
@Test
void shouldDestroyMasterKeyAfterDeletingUserKey() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
service.destroyMasterKey();
@@ -121,10 +115,11 @@ class LmkServiceTest {
@Test
void shouldReturnStatusFalseWhenMasterKeyDoesNotExist() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
Mockito.when(pcieCryptoService.checkLmk()).thenReturn(false);
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
MasterKeyStateResult result = service.queryMasterKeyStatus();
@@ -136,11 +131,12 @@ class LmkServiceTest {
@Test
void shouldReturnStatusTrueAndSeedMacWhenMasterKeyExists() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
Mockito.when(pcieCryptoService.checkLmk()).thenReturn(true);
Mockito.when(pcieCryptoService.exportLmkSeedMac()).thenReturn(new byte[] {(byte) 0xAA, (byte) 0xBB});
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
MasterKeyStateResult result = service.queryMasterKeyStatus();
@@ -151,13 +147,14 @@ class LmkServiceTest {
@Test
void shouldExportIkPublicKeyHexViaDedicatedIkApi() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
BackupDataResult publicKey = new BackupDataResult();
publicKey.setLength(new EccRefPublicKey().size());
publicKey.setData(sequentialBytes(new EccRefPublicKey().size(), 0x31));
Mockito.when(pcieCryptoService.exportIkPublicKey(2)).thenReturn(publicKey);
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
String result = service.exportIkPublicKeyHex();
@@ -169,6 +166,7 @@ class LmkServiceTest {
@Test
void shouldBuildBackupPacketForPacketContract() throws Exception {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
BackupDataResult lmkBackup = new BackupDataResult();
lmkBackup.setLength(20);
@@ -196,7 +194,7 @@ class LmkServiceTest {
Mockito.when(pcieCryptoService.backupUserKey(1, 0, 120)).thenReturn(userSignBackup);
Mockito.when(pcieCryptoService.backupUserKey(1, 1, 120)).thenReturn(userEncBackup);
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
MasterKeyBackupPacket packet = service.buildBackupPacket(2);
int componentBytesLength = 3 * 64;
@@ -226,6 +224,7 @@ class LmkServiceTest {
@Test
void shouldReuseSingleBackupRoundAcrossTwoPacketBuilds() throws Exception {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
BackupDataResult lmkBackupRound1 = new BackupDataResult();
@@ -279,7 +278,7 @@ class LmkServiceTest {
Mockito.when(pcieCryptoService.backupUserKey(1, 0, 120)).thenReturn(userSignRound1, userSignRound2);
Mockito.when(pcieCryptoService.backupUserKey(1, 1, 120)).thenReturn(userEncRound1, userEncRound2);
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
MasterKeyBackupPacket packet1 = service.buildBackupPacket(1);
MasterKeyBackupPacket packet2 = service.buildBackupPacket(2);
@@ -334,12 +333,13 @@ class LmkServiceTest {
@Test
void shouldRecoverAllKeyPacketsInOrder() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
MasterKeyRecoveryResult recoveryResult = new MasterKeyRecoveryResult();
recoveryResult.setLmkSeedMac(hex("1112131415161718"));
recoveryResult.setDeviceStatus(new DeviceStatusResult());
Mockito.when(pcieCryptoService.recoverMasterKeyMaterial(Mockito.any())).thenReturn(recoveryResult);
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
MasterKeyBackupPacket packet1 = recoverPacketFixture(1);
MasterKeyBackupPacket packet2 = recoverPacketFixture(2);
@@ -372,6 +372,7 @@ class LmkServiceTest {
@Test
void shouldHashRawDataBeforeInternalSign() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
BackupDataResult digestResult = new BackupDataResult();
digestResult.setLength(32);
@@ -387,7 +388,7 @@ class LmkServiceTest {
Mockito.when(pcieCryptoService.digest(Mockito.any())).thenReturn(digestResult);
Mockito.when(pcieCryptoService.signIk(Mockito.any())).thenReturn(signResult);
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
String signatureHex = service.signIk("1223");
@@ -406,6 +407,7 @@ class LmkServiceTest {
@Test
void shouldHashRawDataBeforeInternalVerify() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
+ MasterKeyActivateRepository masterKeyActivateRepository = Mockito.mock(MasterKeyActivateRepository.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
BackupDataResult digestResult = new BackupDataResult();
digestResult.setLength(32);
@@ -417,7 +419,7 @@ class LmkServiceTest {
});
Mockito.when(pcieCryptoService.digest(Mockito.any())).thenReturn(digestResult);
- LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
+ LmkService service = new LmkServiceImpl(pcieCryptoService, properties, masterKeyActivateRepository);
service.verifyIk("1223", "aabb");