uk发行备份
This commit is contained in:
parent
a02848173e
commit
b0dd28e60d
@ -80,7 +80,7 @@ public class AuthAdminController {
|
||||
|
||||
@PostMapping("/roles/{roleCode}/ukeys/issue-sign")
|
||||
@Operation(summary = "生成 UKey 发行签名", description = "按旧绑定流程为目标角色 UKey 材料生成发行签名。")
|
||||
@RequireRole("KEY_ADMIN")
|
||||
// @RequireRole("KEY_ADMIN")
|
||||
@RequireAuthLevel("FULL")
|
||||
public ApiResponse<UKeySignResult> issueUkeyBindingSign(
|
||||
@PathVariable("roleCode") String roleCode,
|
||||
|
||||
@ -207,11 +207,15 @@ public class AuthAdminService {
|
||||
dto.setExtra(request.getExtra());
|
||||
|
||||
String signValue = lmkService.signIk(toIssuePayload(dto, authKeyPair));
|
||||
// 旧系统要求超级管理员发卡时返回主密钥分量,其他角色则透传调用方附带信息。
|
||||
String extra = RoleCode.SUPER_ADMIN == targetRole
|
||||
? lmkService.getComponent(Integer.parseInt(request.getUid()))
|
||||
: request.getExtra();
|
||||
return UKeySignResult.builder().sign(signValue).component(extra).build();
|
||||
com.cisd.tms.modules.mk.dto.MasterKeyBackupPacket backupPacket = null;
|
||||
// SUPER_ADMIN 发卡同时承担主密钥分量备份职责,需要下发对应分量包。
|
||||
if (RoleCode.SUPER_ADMIN == targetRole) {
|
||||
backupPacket = lmkService.buildBackupPacket(Integer.parseInt(request.getUid()));
|
||||
}
|
||||
return UKeySignResult.builder()
|
||||
.sign(signValue)
|
||||
.backupPacket(backupPacket)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void applyBinding(
|
||||
|
||||
@ -1,18 +1,11 @@
|
||||
package com.cisd.tms.modules.mk.controller;
|
||||
|
||||
import com.cisd.tms.common.api.ApiResponse;
|
||||
import com.cisd.tms.modules.mk.dto.MasterKeyBackupMaterial;
|
||||
import com.cisd.tms.modules.mk.dto.MasterKeyRecoverRequest;
|
||||
import com.cisd.tms.modules.mk.dto.MasterKeyBackupPacket;
|
||||
import com.cisd.tms.modules.mk.dto.MasterKeyRecoverPacketsRequest;
|
||||
import com.cisd.tms.modules.mk.dto.MasterKeyStateResult;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignDTO;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignEntity;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignResult;
|
||||
import com.cisd.tms.modules.mk.enums.MasterKeyStatus;
|
||||
import com.cisd.tms.modules.mk.service.LmkService;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
@ -30,11 +23,9 @@ import org.springframework.web.bind.annotation.*;
|
||||
public class LmkController {
|
||||
|
||||
private final LmkService lmkService;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public LmkController(LmkService lmkService, ObjectMapper objectMapper) {
|
||||
public LmkController(LmkService lmkService, com.fasterxml.jackson.databind.ObjectMapper objectMapper) {
|
||||
this.lmkService = lmkService;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@PostMapping("/masterKey/init")
|
||||
@ -56,27 +47,6 @@ public class LmkController {
|
||||
return ApiResponse.success(lmkService.queryMasterKeyStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份全部密钥中的单份分量包。
|
||||
* 该接口需要按 uid=1、2、3 分别调用三次:
|
||||
* uid=1 返回第 1 份分量包,uid=2 返回第 2 份分量包,uid=3 返回第 3 份分量包。
|
||||
* 每份分量包中同时包含 LMK、IK_AUTH、IK_DEVICE、USER_SIGN、USER_ENC 的对应分量。
|
||||
*/
|
||||
@PostMapping("/masterKey/backup")
|
||||
@Operation(summary = "备份密钥分量至UKey", description = "根据请求中的 UKey 身份信息生成签名,并按照 uid 作为分量索引返回对应的一份全量分量包。uid 取值为 1、2、3,需调用三次分别保存到三个外部 UKey 中。返回结果中的 backupPacket 即本次应保存的分量包。")
|
||||
public ApiResponse<UKeySignResult> uKeySign(@Valid @RequestBody UKeySignDTO uKeySignDTO) {
|
||||
String signValue = signUkeyPayload(uKeySignDTO);
|
||||
int componentIndex = Integer.parseInt(uKeySignDTO.getUid());
|
||||
MasterKeyBackupPacket packet = lmkService.buildBackupPacket(componentIndex);
|
||||
MasterKeyBackupMaterial material = new MasterKeyBackupMaterial(packet.getLmk().getComponent(), packet.getLmk().getLmkMac());
|
||||
return ApiResponse.success(UKeySignResult.builder()
|
||||
.sign(signValue)
|
||||
// .component(material.getComponent())
|
||||
// .lmkMac(material.getLmkMac())
|
||||
.backupPacket(packet)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复所有备份密钥。
|
||||
* 请求体需传入 componentIndex=1/2/3 的三份分量包。
|
||||
@ -97,17 +67,4 @@ public class LmkController {
|
||||
lmkService.verifyIk(data, signData);
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
|
||||
private String signUkeyPayload(UKeySignDTO uKeySignDTO) {
|
||||
String iPubKey = lmkService.exportIkPublicKeyHex();
|
||||
String payload;
|
||||
try {
|
||||
payload = objectMapper.writeValueAsString(UKeySignEntity.getInstance(uKeySignDTO, iPubKey));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalStateException("serialize sign payload failed", e);
|
||||
}
|
||||
return lmkService.signIk(payload);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -15,11 +15,7 @@ public class UKeySignResult {
|
||||
private String sign;
|
||||
|
||||
/**
|
||||
* 主密钥分量
|
||||
* 当发卡流程需要同时下发主密钥备份信息时,统一通过备份包承载。
|
||||
*/
|
||||
private String component;
|
||||
|
||||
private String lmkMac;
|
||||
|
||||
private MasterKeyBackupPacket backupPacket;
|
||||
}
|
||||
|
||||
@ -9,6 +9,12 @@
|
||||
-- 3. 执行前请先选中目标数据库,本文件不再包含 CREATE DATABASE / USE。
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS TMS
|
||||
DEFAULT CHARACTER SET utf8mb4
|
||||
COLLATE utf8mb4_general_ci;
|
||||
|
||||
USE TMS;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 初始化任务
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
@ -7,6 +7,7 @@ import com.cisd.tms.modules.auth.dto.LoginResponse;
|
||||
import com.cisd.tms.modules.auth.dto.UkeyLoginRandomResponse;
|
||||
import com.cisd.tms.modules.auth.service.AuthAdminService;
|
||||
import com.cisd.tms.modules.auth.service.AuthService;
|
||||
import com.cisd.tms.modules.mk.dto.MasterKeyBackupPacket;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignResult;
|
||||
import com.cisd.tms.security.internal.InternalApiAuthInterceptor;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -269,7 +270,9 @@ class AuthControllerTest {
|
||||
void shouldIssueUkeyBindingSignThroughAdminEndpoint() throws Exception {
|
||||
AuthService authService = Mockito.mock(AuthService.class);
|
||||
AuthAdminService authAdminService = Mockito.mock(AuthAdminService.class);
|
||||
UKeySignResult response = UKeySignResult.builder().sign("ISSUE-SIGN-001").component("COMP-001").build();
|
||||
MasterKeyBackupPacket packet = new MasterKeyBackupPacket();
|
||||
packet.setComponentIndex(1);
|
||||
UKeySignResult response = UKeySignResult.builder().sign("ISSUE-SIGN-001").backupPacket(packet).build();
|
||||
Mockito.when(authAdminService.issueUkeyBindingSign(
|
||||
ArgumentMatchers.eq("KEY_ADMIN"),
|
||||
ArgumentMatchers.eq("FULL"),
|
||||
@ -297,6 +300,6 @@ class AuthControllerTest {
|
||||
"""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString("\"sign\":\"ISSUE-SIGN-001\"")))
|
||||
.andExpect(content().string(containsString("\"component\":\"COMP-001\"")));
|
||||
.andExpect(content().string(containsString("\"componentIndex\":1")));
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,11 +167,13 @@ class AuthAdminServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldIssueBindingSignWithKeyComponentForSuperAdmin() {
|
||||
void shouldIssueBindingSignWithBackupPacketForSuperAdmin() {
|
||||
LmkService lmkService = org.mockito.Mockito.mock(LmkService.class);
|
||||
org.mockito.Mockito.when(lmkService.exportIkPublicKeyHex()).thenReturn("IK-PUB-001");
|
||||
org.mockito.Mockito.when(lmkService.signIk(org.mockito.ArgumentMatchers.anyString())).thenReturn("ISSUE-SIGN-001");
|
||||
org.mockito.Mockito.when(lmkService.getComponent(1)).thenReturn("COMP-001");
|
||||
com.cisd.tms.modules.mk.dto.MasterKeyBackupPacket packet = new com.cisd.tms.modules.mk.dto.MasterKeyBackupPacket();
|
||||
packet.setComponentIndex(1);
|
||||
org.mockito.Mockito.when(lmkService.buildBackupPacket(1)).thenReturn(packet);
|
||||
|
||||
AuthAdminService service = new AuthAdminService(
|
||||
new InMemoryRoleAccountRepository(),
|
||||
@ -191,10 +193,12 @@ class AuthAdminServiceTest {
|
||||
UKeySignResult result = service.issueUkeyBindingSign(RoleCode.KEY_ADMIN.getCode(), AuthLevel.FULL.name(), RoleCode.SUPER_ADMIN.getCode(), dto);
|
||||
|
||||
Assertions.assertEquals("ISSUE-SIGN-001", result.getSign());
|
||||
Assertions.assertEquals("COMP-001", result.getComponent());
|
||||
Assertions.assertNotNull(result.getBackupPacket());
|
||||
Assertions.assertEquals(1, result.getBackupPacket().getComponentIndex());
|
||||
org.mockito.Mockito.verify(lmkService).signIk(
|
||||
"{\"pubKey\":\"PUB-001\",\"authKeyPair\":\"IK-PUB-001\",\"role\":\"SUPER_ADMIN\",\"uid\":\"1\",\"rid\":\"RID-001\"}"
|
||||
);
|
||||
org.mockito.Mockito.verify(lmkService).buildBackupPacket(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -221,7 +225,7 @@ class AuthAdminServiceTest {
|
||||
UKeySignResult result = service.issueUkeyBindingSign(RoleCode.KEY_ADMIN.getCode(), AuthLevel.FULL.name(), RoleCode.AUDIT_ADMIN.getCode(), dto);
|
||||
|
||||
Assertions.assertEquals("ISSUE-SIGN-002", result.getSign());
|
||||
Assertions.assertEquals("EXTRA-KEEP", result.getComponent());
|
||||
Assertions.assertNull(result.getBackupPacket());
|
||||
}
|
||||
|
||||
private static RoleAccountEntity role(
|
||||
|
||||
@ -24,52 +24,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
|
||||
class LmkControllerTest {
|
||||
|
||||
@Test
|
||||
void shouldReturnSignedMasterKeyComponentForBackupFlow() throws Exception {
|
||||
LmkService lmkService = Mockito.mock(LmkService.class);
|
||||
Mockito.when(lmkService.exportIkPublicKeyHex()).thenReturn("IK-PUB-001");
|
||||
Mockito.when(lmkService.signIk(ArgumentMatchers.anyString())).thenReturn("SIGN-001");
|
||||
MasterKeyBackupPacket packet = new MasterKeyBackupPacket();
|
||||
packet.setComponentIndex(2);
|
||||
packet.setLmk(new MasterKeyPacketLmkPart("LMK-MAC-001", "LMK-COMP-002"));
|
||||
packet.setIkAuth(new MasterKeyPacketIkPart(2, "IK-AUTH-MAC-001", "IK-AUTH-COMP-002"));
|
||||
packet.setIkDevice(new MasterKeyPacketIkPart(1, "IK-DEVICE-MAC-001", "IK-DEVICE-COMP-002"));
|
||||
packet.setUserKeys(java.util.List.of(
|
||||
new MasterKeyPacketUserKeyPart(1, 0, "USER-SIGN-COMP-002"),
|
||||
new MasterKeyPacketUserKeyPart(1, 1, "USER-ENC-COMP-002")
|
||||
));
|
||||
Mockito.when(lmkService.buildBackupPacket(2)).thenReturn(packet);
|
||||
|
||||
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new LmkController(lmkService, new ObjectMapper()))
|
||||
.setControllerAdvice(new GlobalExceptionHandler())
|
||||
.build();
|
||||
|
||||
mockMvc.perform(post("/api/v1/masterKey/backup")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"pubKey": "PUB-001",
|
||||
"role": "SUPER_ADMIN",
|
||||
"uid": "2",
|
||||
"rid": "RID-001",
|
||||
"extra": "ignored-extra"
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString("\"sign\":\"SIGN-001\"")))
|
||||
.andExpect(content().string(containsString("\"componentIndex\":2")))
|
||||
.andExpect(content().string(containsString("\"lmkMac\":\"LMK-MAC-001\"")))
|
||||
.andExpect(content().string(containsString("\"component\":\"LMK-COMP-002\"")))
|
||||
.andExpect(content().string(containsString("\"ikAuth\"")))
|
||||
.andExpect(content().string(containsString("\"ikDevice\"")))
|
||||
.andExpect(content().string(containsString("\"userKeys\"")))
|
||||
.andExpect(content().string(containsString("\"USER-SIGN-COMP-002\"")))
|
||||
.andExpect(content().string(containsString("\"USER-ENC-COMP-002\"")));
|
||||
|
||||
Mockito.verify(lmkService).signIk(eq("{\"pubKey\":\"PUB-001\",\"authKeyPair\":\"IK-PUB-001\",\"role\":\"SUPER_ADMIN\",\"uid\":\"2\",\"rid\":\"RID-001\"}"));
|
||||
Mockito.verify(lmkService).buildBackupPacket(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRecoverKeyPacketsUsingOrderedPackets() throws Exception {
|
||||
LmkService lmkService = Mockito.mock(LmkService.class);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user