密钥恢复

This commit is contained in:
liulu 2024-10-29 11:40:42 +08:00
parent f7e63fadb9
commit e45f9624e4
4 changed files with 95 additions and 64 deletions

View File

@ -5,14 +5,17 @@ import com.sunyard.chsm.enums.KeyStatus;
import com.sunyard.chsm.model.Option;
import com.sunyard.chsm.model.R;
import com.sunyard.chsm.service.KeyInfoService;
import com.sunyard.ssp.common.exception.SspwebException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -62,10 +65,26 @@ public class KeyInfoController {
*/
@PostMapping("/update")
public R<Void> save(@Valid @RequestBody KeyInfoDTO.Update update) {
keyInfoService.update(update);
keyInfoService.update(update);
return R.ok();
}
/**
* 恢复密钥(文件上传)
*
* @param file 密钥备份文件
* @return id
*/
@PostMapping("/recovery")
public R<String> recoveryKey(MultipartFile file) {
try {
String s = keyInfoService.recoveryKey(file.getBytes());
return R.ok(s);
} catch (IOException e) {
throw new SspwebException("获取文件内容异常");
}
}
/**
* 启用密钥
*
@ -102,18 +121,6 @@ public class KeyInfoController {
return R.ok();
}
/**
* 恢复密钥
*
* @param param 密钥id
* @return id
*/
@PostMapping("/recovery")
public R<Void> recoveryKey(@Valid @RequestBody KeyInfoDTO.IDs param) {
keyInfoService.recoveryKey(param.getIds());
return R.ok();
}
/**
* 销毁密钥
*

View File

@ -116,6 +116,7 @@ public abstract class KeyInfoDTO {
@NotNull(message = "结束日期不能为空")
private LocalDate endTime;
}
}

View File

@ -19,13 +19,13 @@ public interface KeyInfoService {
byte[] backupKey(KeyInfoDTO.Backup backup);
String recoveryKey(byte[] content);
void enableKey(List<Long> ids);
void disableKey(List<Long> ids);
void archiveKey(List<Long> ids);
void recoveryKey(List<Long> ids);
void destroyKey(List<Long> ids);
}

View File

@ -19,6 +19,8 @@ import com.sunyard.chsm.sdf.SdfApiService;
import com.sunyard.chsm.sdf.model.EccKey;
import com.sunyard.chsm.service.KeyInfoService;
import com.sunyard.chsm.utils.JsonUtils;
import com.sunyard.ssp.common.exception.SspwebException;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.BeanUtils;
@ -26,9 +28,14 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
@ -192,30 +199,6 @@ public class KeyInfoServiceImpl implements KeyInfoService {
}
@Override
public byte[] backupKey(KeyInfoDTO.Backup backup) {
LocalDate plussed = backup.getStartTime().plusDays(100);
Assert.isTrue(plussed.isAfter(backup.getEndTime()), "备份密钥创建时间范围不能超过100天");
List<KeyInfo> keyInfos = keyInfoMapper.selectList(
new LambdaQueryWrapper<KeyInfo>()
.eq(KeyInfo::getKeyType, backup.getKeyType())
.gt(KeyInfo::getCreateTime, LocalDateTime.of(backup.getStartTime(), LocalTime.MIN))
.lt(KeyInfo::getCreateTime, LocalDateTime.of(backup.getEndTime(), LocalTime.MAX))
);
StringBuilder builder = new StringBuilder();
for (KeyInfo keyInfo : keyInfos) {
List<KeyRecord> records = spKeyRecordMapper.selectList(
new LambdaQueryWrapper<KeyRecord>()
.eq(KeyRecord::getKeyId, keyInfo.getId())
);
keyInfo.setRecords(records);
builder.append(JsonUtils.toJsonString(records)).append(System.lineSeparator());
}
return builder.toString().getBytes(StandardCharsets.UTF_8);
}
private KeyRecord genKeyRecord(KeyInfo info) {
KeyRecord record = new KeyRecord();
record.setId(IdWorker.getId());
@ -244,6 +227,70 @@ public class KeyInfoServiceImpl implements KeyInfoService {
return record;
}
@Override
public byte[] backupKey(KeyInfoDTO.Backup backup) {
LocalDate plussed = backup.getStartTime().plusDays(100);
Assert.isTrue(plussed.isAfter(backup.getEndTime()), "备份密钥创建时间范围不能超过100天");
List<KeyInfo> keyInfos = keyInfoMapper.selectList(
new LambdaQueryWrapper<KeyInfo>()
.eq(KeyInfo::getKeyType, backup.getKeyType())
.gt(KeyInfo::getCreateTime, LocalDateTime.of(backup.getStartTime(), LocalTime.MIN))
.lt(KeyInfo::getCreateTime, LocalDateTime.of(backup.getEndTime(), LocalTime.MAX))
);
StringBuilder builder = new StringBuilder();
for (KeyInfo keyInfo : keyInfos) {
List<KeyRecord> records = spKeyRecordMapper.selectList(
new LambdaQueryWrapper<KeyRecord>()
.eq(KeyRecord::getKeyId, keyInfo.getId())
);
keyInfo.setRecords(records);
builder.append(JsonUtils.toJsonString(records)).append(System.lineSeparator());
}
return builder.toString().getBytes(StandardCharsets.UTF_8);
}
@Override
public String recoveryKey(byte[] content) {
int suc = 0, count = 0, err = 0, exd = 0;
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content);
@Cleanup BufferedReader reader = new BufferedReader(new InputStreamReader(byteArrayInputStream, StandardCharsets.UTF_8));
String line;
while (true) {
try {
if ((line = reader.readLine()) == null) break;
} catch (IOException e) {
throw new SspwebException("文件读取异常");
}
if (ObjectUtils.isEmpty(line)) {
continue;
}
count++;
try {
KeyInfo info = JsonUtils.parse(line, KeyInfo.class);
KeyInfo exist = keyInfoMapper.selectById(info.getId());
if (exist != null) {
exd++;
continue;
}
spKeyRecordMapper.delete(
new LambdaQueryWrapper<KeyRecord>()
.eq(KeyRecord::getKeyId, info.getId())
);
keyInfoMapper.insert(info);
info.getRecords().forEach(spKeyRecordMapper::insert);
suc++;
} catch (Exception ex) {
err++;
}
}
return String.format("恢复完成,共%d条数据,跳过已经存在的密钥%d条,恢复成功%d条,解析失败%d条", count, exd, suc, err);
}
@Override
public void enableKey(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
@ -314,30 +361,6 @@ public class KeyInfoServiceImpl implements KeyInfoService {
);
}
@Override
public void recoveryKey(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
return;
}
List<KeyInfo> keyInfos = keyInfoMapper.selectBatchIds(ids);
if (CollectionUtils.isEmpty(keyInfos)) {
log.warn("recoveryKey no exist key with ids: {}", ids.stream().map(String::valueOf).collect(Collectors.joining(",")));
return;
}
List<String> unNormalCodes = keyInfos.stream()
.filter(it -> !Objects.equals(KeyStatus.ARCHIVED.getCode(), it.getStatus()))
.map(KeyInfo::getCode)
.collect(Collectors.toList());
Assert.isTrue(CollectionUtils.isEmpty(unNormalCodes),
"密钥id: " + String.join(",", unNormalCodes) + "不是归档状态, 无法恢复");
keyInfoMapper.update(
new LambdaUpdateWrapper<KeyInfo>()
.set(KeyInfo::getStatus, KeyStatus.DISABLED.getCode())
.in(KeyInfo::getId, ids)
);
}
@Override
public void destroyKey(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {