设备激活
This commit is contained in:
parent
e7f9c1d183
commit
284b2bb9f6
7
pom.xml
7
pom.xml
@ -115,6 +115,13 @@
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>1.10.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sunyard.cisd</groupId>
|
||||
<artifactId>device-fingerprint-tool</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -29,7 +29,6 @@ public class NetworkConfigController {
|
||||
|
||||
@Operation(summary = "获取所有网卡名", description = "获取系统中所有网卡名称")
|
||||
@GetMapping("/card/eth-names")
|
||||
@AuditedOperation(module = ModuleCode.DEVICE, action = ActionType.CREATE, summary = "获取所有网卡名")
|
||||
public ApiResponse<List<String>> getEthDeviceNames() {
|
||||
return ApiResponse.success(networkConfigService.getEthDeviceNames());
|
||||
}
|
||||
|
||||
@ -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; }
|
||||
}
|
||||
@ -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<Void> Activate(@RequestBody MasterKeyActivateRequest masterKeyActivateRequest) {
|
||||
masterKeyActivateService.activate(masterKeyActivateRequest);
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/masterKey/activate/info")
|
||||
@Operation(summary = "查询设备激活信息", description = "返回设备型号、设备名称、设备序列号、设备版本、设备状态、异常原因。")
|
||||
public ApiResponse<MasterKeyActivateInfoResponse> getMasterKeyActivateInfo() {
|
||||
return ApiResponse.success(masterKeyActivateService.getMasterKeyActivateInfo());
|
||||
}
|
||||
|
||||
private void validatePacketIndexes(List<MasterKeyBackupPacket> packets) {
|
||||
if (packets == null || packets.size() != 2) {
|
||||
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "packets数量必须为2");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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<MasterKeyActivateEntity> {
|
||||
}
|
||||
@ -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<MasterKeyActivateEntity> find();
|
||||
void update(MasterKeyActivateEntity masterKeyActivateEntity);
|
||||
}
|
||||
@ -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<MasterKeyActivateEntity> find() {
|
||||
LambdaQueryWrapper<MasterKeyActivateEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
wrapper.last("LIMIT 1");
|
||||
|
||||
MasterKeyActivateEntity entity = masterKeyActivateMapper.selectOne(wrapper);
|
||||
return Optional.ofNullable(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(MasterKeyActivateEntity masterKeyActivateEntity) {
|
||||
// LambdaQueryWrapper<MasterKeyActivateEntity> 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<MasterKeyActivateEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
//
|
||||
// wrapper.last("LIMIT 1");
|
||||
//
|
||||
// MasterKeyActivateEntity entity = masterKeyActivateMapper.selectOne(wrapper);
|
||||
//
|
||||
// entity.setEverInitialized(activateStatus);
|
||||
// masterKeyActivateMapper.updateById(entity);
|
||||
// }
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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<String> 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<DeviceSoftwareVersionEntity> version = deviceSoftwareVersionRepository.findByComponentCode("TMS");
|
||||
return version.map(DeviceSoftwareVersionEntity::getCurrentVersion).map(MasterKeyActivateServiceImpl::trim).orElse("");
|
||||
}
|
||||
|
||||
private static String trim(String value) {
|
||||
return value == null ? "" : value.trim();
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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");
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user