初始化主密钥
This commit is contained in:
parent
5dd7b9ee7e
commit
4ae46ed32d
@ -1,13 +1,25 @@
|
||||
package com.sunyard.chsm.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sunyard.chsm.model.entity.Device;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author liulu
|
||||
* @since 2024/10/17
|
||||
*/
|
||||
@Mapper
|
||||
public interface SpDeviceMapper extends BaseMapper<Device> {
|
||||
|
||||
default List<Device> selectConnedList() {
|
||||
return selectList(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getConnected, true)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ public class TmkInfo {
|
||||
|
||||
private String deviceSerial;
|
||||
private String encTmk;
|
||||
private String pubKey;
|
||||
|
||||
private String remark;
|
||||
private LocalDateTime createTime;
|
||||
|
@ -2,14 +2,16 @@ package com.sunyard.chsm.sdf.adapter;
|
||||
|
||||
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
||||
import com.sunyard.chsm.sdf.model.EccKey;
|
||||
import com.sunyard.chsm.sdf.model.EccPriKey;
|
||||
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||
import com.sunyard.chsm.sdf.util.LangUtils;
|
||||
import com.sunyard.chsm.utils.gm.BCECUtils;
|
||||
import com.sunyard.chsm.utils.gm.BCSM2Utils;
|
||||
import lombok.SneakyThrows;
|
||||
import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
import org.bouncycastle.util.Arrays;
|
||||
import org.bouncycastle.util.BigIntegers;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@ -70,10 +72,10 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
||||
public byte[] exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
||||
BigInteger d = new BigInteger(1, getD());
|
||||
ECPoint q = BCSM2Utils.G_POINT.multiply(d).normalize();
|
||||
return new EccPubKey(256, q.getXCoord().getEncoded(), q.getYCoord().getEncoded());
|
||||
return LangUtils.merge(q.getXCoord().getEncoded(), q.getYCoord().getEncoded());
|
||||
}
|
||||
|
||||
private byte[] getD() {
|
||||
@ -93,7 +95,29 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
|
||||
byte[] x = pubKey.getQ().getXCoord().getEncoded();
|
||||
byte[] y = pubKey.getQ().getYCoord().getEncoded();
|
||||
byte[] d = BigIntegers.asUnsignedByteArray(32, priKey.getD());
|
||||
return new EccKey(new EccPubKey(256, x, y), new EccPriKey(256, d));
|
||||
return new EccKey(LangUtils.merge(x, y), d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, byte[] pubKey, byte[] pucEncDateIn) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] externalEncryptECC(String sessionHandle, byte[] pubKey, byte[] pucData) {
|
||||
if (pubKey[0] == 4) {
|
||||
pubKey = Arrays.copyOfRange(pubKey, 1, 65);
|
||||
}
|
||||
ECPublicKeyParameters parameters = BCECUtils.createECPublicKeyParameters(
|
||||
Arrays.copyOfRange(pubKey, 0, 32),
|
||||
Arrays.copyOfRange(pubKey, 32, 64)
|
||||
);
|
||||
try {
|
||||
byte[] encrypt = BCSM2Utils.encrypt(parameters, pucData);
|
||||
return Arrays.copyOfRange(encrypt, 1, encrypt.length);
|
||||
} catch (InvalidCipherTextException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,11 +2,12 @@ package com.sunyard.chsm.sdf.adapter;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
import com.sunyard.chsm.sdf.context.AlgId;
|
||||
import com.sunyard.chsm.sdf.lib.SdfLibrary;
|
||||
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
||||
import com.sunyard.chsm.sdf.model.EccKey;
|
||||
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||
import com.sunyard.chsm.sdf.model.SDF_DeviceInfo;
|
||||
import com.sunyard.chsm.sdf.util.LangUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.Assert;
|
||||
@ -117,15 +118,28 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
||||
public byte[] exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
||||
byte[] pubKey = new byte[132];
|
||||
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||
sdfLibrary.SDF_ExportEncPublicKey_ECC(hSessionHandle, uiKeyIndex, pubKey);
|
||||
return new EccPubKey(256, Arrays.copyOfRange(pubKey, 36, 68), Arrays.copyOfRange(pubKey, 100, 132));
|
||||
return LangUtils.merge(Arrays.copyOfRange(pubKey, 36, 68), Arrays.copyOfRange(pubKey, 100, 132));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EccKey generateKeyPairECC(String sessionHandle, String alg, int uiKeyBits) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, byte[] pubKey, byte[] pucEncDateIn) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] externalEncryptECC(String sessionHandle, byte[] pubKey, byte[] pucData) {
|
||||
byte[] encData = new byte[128 + 32 + 4 + pucData.length];
|
||||
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||
sdfLibrary.SDF_ExternalEncrypt_ECC(hSessionHandle, getAlgId(AlgId.SGD_SM2_3), pubKey, pucData, pucData.length, encData);
|
||||
return encData;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package com.sunyard.chsm.sdf.adapter;
|
||||
|
||||
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
||||
import com.sunyard.chsm.sdf.model.EccKey;
|
||||
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||
|
||||
/**
|
||||
* @author liulu
|
||||
@ -54,9 +53,9 @@ public interface SdfApiAdapter {
|
||||
* 导出ECC加密公钥
|
||||
*
|
||||
* @param uiKeyIndex 密码设备存储的ECC密钥对索引值
|
||||
* @return pucPublicKeyEcc 返回ECC加密公钥
|
||||
* @return pucPublicKeyEcc 返回ECC加密公钥x+y
|
||||
*/
|
||||
EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex);
|
||||
byte[] exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex);
|
||||
|
||||
/**
|
||||
* 产生ECC密钥对并输出
|
||||
@ -68,4 +67,10 @@ public interface SdfApiAdapter {
|
||||
EccKey generateKeyPairECC(String sessionHandle, String alg, int uiKeyBits);
|
||||
|
||||
|
||||
byte[] exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, byte[] pubKey, byte[] pucEncDateIn);
|
||||
|
||||
|
||||
byte[] externalEncryptECC(String sessionHandle, byte[] pubKey, byte[] pucData);
|
||||
|
||||
|
||||
}
|
||||
|
@ -12,10 +12,10 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
public class EccKey {
|
||||
|
||||
private EccPubKey pubKey;
|
||||
private EccPriKey priKey;
|
||||
private byte[] pubKey;
|
||||
private byte[] priKey;
|
||||
|
||||
public EccKey(EccPubKey pubKey, EccPriKey priKey) {
|
||||
public EccKey(byte[] pubKey, byte[] priKey) {
|
||||
this.pubKey = pubKey;
|
||||
this.priKey = priKey;
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package com.sunyard.chsm.controller;
|
||||
|
||||
import com.sunyard.chsm.service.DeviceService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 主密钥管理
|
||||
*
|
||||
* @author liulu
|
||||
* @since 2024/11/8
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/tmk")
|
||||
public class TmkController {
|
||||
|
||||
@Resource
|
||||
private DeviceService deviceService;
|
||||
|
||||
/**
|
||||
* 初始化主密钥
|
||||
*/
|
||||
@PostMapping("/init")
|
||||
public void initTmk() {
|
||||
deviceService.initTmk();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -21,4 +21,7 @@ public interface DeviceService {
|
||||
void update(DeviceDTO.DeviceSave update);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
void initTmk();
|
||||
|
||||
}
|
||||
|
@ -8,9 +8,19 @@ import com.sunyard.chsm.dto.DeviceDTO;
|
||||
import com.sunyard.chsm.enums.ManufacturerEnum;
|
||||
import com.sunyard.chsm.enums.ManufacturerModelEnum;
|
||||
import com.sunyard.chsm.mapper.SpDeviceMapper;
|
||||
import com.sunyard.chsm.mapper.TmkInfoMapper;
|
||||
import com.sunyard.chsm.model.entity.Device;
|
||||
import com.sunyard.chsm.model.entity.TmkInfo;
|
||||
import com.sunyard.chsm.sdf.adapter.BcSdfApiAdaptor;
|
||||
import com.sunyard.chsm.sdf.adapter.SdfApiAdapter;
|
||||
import com.sunyard.chsm.sdf.adapter.SdfApiAdapterFactory;
|
||||
import com.sunyard.chsm.sdf.context.DeviceContext;
|
||||
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
||||
import com.sunyard.chsm.service.DeviceService;
|
||||
import com.sunyard.ssp.modules.sysconf.paramconf.entity.ParamConf;
|
||||
import com.sunyard.ssp.modules.sysconf.paramconf.mapper.ParamConfMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -36,6 +46,10 @@ public class DeviceServiceImpl implements DeviceService {
|
||||
|
||||
@Resource
|
||||
private SpDeviceMapper spDeviceMapper;
|
||||
@Resource
|
||||
private ParamConfMapper paramConfMapper;
|
||||
@Resource
|
||||
private TmkInfoMapper tmkInfoMapper;
|
||||
|
||||
@Override
|
||||
public Page<DeviceDTO.DeviceView> selectPageList(DeviceDTO.Query query) {
|
||||
@ -171,6 +185,70 @@ public class DeviceServiceImpl implements DeviceService {
|
||||
spDeviceMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initTmk() {
|
||||
ParamConf tmkInit = paramConfMapper.selectByKey("tmk_init");
|
||||
Assert.isTrue(tmkInit == null || !"true".equals(tmkInit.getValue()), "主密钥已经初始化");
|
||||
List<Device> conned = spDeviceMapper.selectConnedList();
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (CollectionUtils.isEmpty(conned)) {
|
||||
//
|
||||
BcSdfApiAdaptor sdfApi = new BcSdfApiAdaptor();
|
||||
byte[] sk = sdfApi.generateRandom("", 16);
|
||||
|
||||
byte[] publicKey = sdfApi.exportEncPublicKeyECC("", 1);
|
||||
byte[] encSk = sdfApi.externalEncryptECC("", publicKey, sk);
|
||||
|
||||
TmkInfo info = new TmkInfo();
|
||||
info.setId(IdWorker.getId());
|
||||
info.setCreateTime(now);
|
||||
info.setDeviceSerial(sdfApi.getDeviceInfo("").getDeviceSerial());
|
||||
info.setEncTmk(Hex.toHexString(encSk));
|
||||
info.setPubKey(Hex.toHexString(publicKey));
|
||||
tmkInfoMapper.insert(info);
|
||||
return;
|
||||
}
|
||||
Device device = conned.iterator().next();
|
||||
|
||||
DeviceContext context = new DeviceContext();
|
||||
context.setManufacturer(device.getManufacturer());
|
||||
context.setManufacturerModel(device.getManufacturerModel());
|
||||
context.setServiceIp(device.getServiceIp());
|
||||
context.setServicePort(device.getServicePort());
|
||||
SdfApiAdapter sdfApi = SdfApiAdapterFactory.newInstance(context);
|
||||
String dh = sdfApi.openDevice();
|
||||
String sh = sdfApi.openSession(dh);
|
||||
DeviceInfo deviceInfo = sdfApi.getDeviceInfo(sh);
|
||||
|
||||
byte[] sk = sdfApi.generateRandom(sh, 16);
|
||||
byte[] publicKey = sdfApi.exportEncPublicKeyECC(sh, 1);
|
||||
byte[] encSk = sdfApi.externalEncryptECC(sh, publicKey, sk);
|
||||
|
||||
TmkInfo info = new TmkInfo();
|
||||
info.setId(IdWorker.getId());
|
||||
info.setCreateTime(now);
|
||||
info.setDeviceSerial(deviceInfo.getDeviceSerial());
|
||||
info.setEncTmk(Hex.toHexString(encSk));
|
||||
info.setPubKey(Hex.toHexString(publicKey));
|
||||
tmkInfoMapper.insert(info);
|
||||
|
||||
//
|
||||
BcSdfApiAdaptor bcApi = new BcSdfApiAdaptor();
|
||||
byte[] bcPubK = bcApi.exportEncPublicKeyECC("", 1);
|
||||
byte[] bcEncSk = sdfApi.exchangeDigitEnvelopeBaseOnECC(sh, 1, bcPubK, encSk);
|
||||
|
||||
TmkInfo bcinfo = new TmkInfo();
|
||||
bcinfo.setId(IdWorker.getId());
|
||||
bcinfo.setCreateTime(now);
|
||||
bcinfo.setDeviceSerial(bcApi.getDeviceInfo("").getDeviceSerial());
|
||||
bcinfo.setEncTmk(Hex.toHexString(bcEncSk));
|
||||
bcinfo.setPubKey(Hex.toHexString(bcPubK));
|
||||
tmkInfoMapper.insert(bcinfo);
|
||||
sdfApi.closeSession(sh);
|
||||
sdfApi.closeDevice(dh);
|
||||
}
|
||||
|
||||
private void checkName(String name) {
|
||||
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getName, name);
|
||||
|
@ -282,13 +282,13 @@ public class KeyInfoServiceImpl implements KeyInfoService {
|
||||
record.setCheckValue(checkHash);
|
||||
} else {
|
||||
EccKey eccKey = sdfApiService.genKeyPairEcc();
|
||||
byte[] d = eccKey.getPriKey().getD();
|
||||
byte[] d = eccKey.getPriKey();
|
||||
byte[] encD = sdfApiService.encryptByTMK(d);
|
||||
record.setKeyData(Hex.toHexString(encD));
|
||||
String checkHash = Hex.toHexString(sdfApiService.hash(d));
|
||||
record.setCheckValue(checkHash);
|
||||
|
||||
byte[] pubKeyBytes = eccKey.getPubKey().getPubKeyBytes();
|
||||
byte[] pubKeyBytes = eccKey.getPubKey();
|
||||
record.setPubKey(Hex.toHexString(pubKeyBytes));
|
||||
record.setPubIdx(record.getPubKey().substring(0, 8));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user