This commit is contained in:
liulu
2024-12-11 11:49:40 +08:00
parent 63fce073dd
commit 3dc061907f
18 changed files with 264 additions and 104 deletions
@@ -9,6 +9,9 @@ import com.sunyard.chsm.mapper.SpDeviceMapper;
import com.sunyard.chsm.model.dto.DeviceCheckRes;
import com.sunyard.chsm.model.entity.CryptoServiceDeviceGroup;
import com.sunyard.chsm.model.entity.Device;
import com.sunyard.chsm.sdf.adapter.SdfApiAdapter;
import com.sunyard.chsm.sdf.adapter.SdfApiAdapterFactory;
import com.sunyard.chsm.sdf.model.EccCipher;
import com.sunyard.chsm.service.TmkService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -48,13 +51,22 @@ public class DeviceManager implements ApplicationRunner {
private Map<Long, List<DeviceContext>> deviceMap = new HashMap<>();
private boolean enableSoftDevice = false;
private TMKContext softContext;
private final TmkService tmkService;
private final SpDeviceMapper spDeviceMapper;
private final CryptoServiceDeviceGroupMapper cryptoServiceDeviceGroupMapper;
private TMKContext chooseOne() {
public void returnContextToPool(TMKContext context) {
Optional.ofNullable(context.getPool())
.ifPresent(it -> {
context.setPool(null);
it.returnObject(context);
});
}
public TMKContext chooseOne() {
RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
AppUser user = (AppUser) attributes.getAttribute(SecurityConstant.ATTRIBUTE_APP_USER, RequestAttributes.SCOPE_REQUEST);
Assert.notNull(user, "登录用户不能为空");
@@ -71,16 +83,40 @@ public class DeviceManager implements ApplicationRunner {
Optional.ofNullable(deviceMap.get(serviceId))
.ifPresent(contexts::addAll);
}
DeviceContext device = getNextDevice(contexts, atomicInteger.getAndIncrement());
try {
return device.getPool().borrowObject();
} catch (Exception e) {
throw new RuntimeException(e);
TMKContext tmkContext;
if (device == null) {
tmkContext = getSoftContext();
} else {
try {
GenericObjectPool<TMKContext> pool = device.getPool();
tmkContext = pool.borrowObject(2000);
tmkContext.setPool(pool);
} catch (Exception e) {
tmkContext = getSoftContext();
}
}
Assert.notNull(tmkContext, "应用: " + user.getName() + "没有可用的密码设备");
return tmkContext;
}
public synchronized TMKContext getSoftContext() {
if (!enableSoftDevice) {
return null;
}
if (Objects.nonNull(softContext)) {
return softContext;
}
byte[] softEncTmk = tmkService.getSoftDeviceEncTmk();
if (softEncTmk == null || softEncTmk.length == 0) {
return null;
}
SdfApiAdapter bcAdapter = SdfApiAdapterFactory.getBcAdapter();
String hk = bcAdapter.importKeyWithISKECC("", 1, EccCipher.fromBytes(softEncTmk));
softContext = new TMKContext();
softContext.setSdfApiAdapter(bcAdapter);
softContext.setKeyHandle(hk);
return softContext;
}
@@ -146,7 +182,7 @@ public class DeviceManager implements ApplicationRunner {
.map(DeviceContext::getDeviceSerial)
.collect(Collectors.toList());
List<DeviceContext> noChanged = old.stream()
List<DeviceContext> nc = old.stream()
.filter(it -> newSerials.contains(it.getDeviceSerial()))
.collect(Collectors.toList());
@@ -154,8 +190,8 @@ public class DeviceManager implements ApplicationRunner {
.filter(it -> !oldSerials.contains(it.getDeviceSerial()))
.collect(Collectors.toList());
noChanged.addAll(waitSync.stream().map(this::mapToContext).filter(Objects::nonNull).collect(Collectors.toList()));
return noChanged;
nc.addAll(waitSync.stream().map(this::mapToContext).filter(Objects::nonNull).collect(Collectors.toList()));
return nc;
});
}
@@ -4,10 +4,13 @@ import com.sunyard.chsm.enums.AlgMode;
import com.sunyard.chsm.enums.KeyAlg;
import com.sunyard.chsm.enums.Padding;
import com.sunyard.chsm.sdf.SdfApiService;
import com.sunyard.chsm.sdf.context.AlgId;
import com.sunyard.chsm.sdf.model.EccKey;
import com.sunyard.chsm.sdf.util.PaddingUtil;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import java.util.function.Function;
/**
* @author liulu
@@ -17,32 +20,51 @@ import javax.annotation.Resource;
public class LoadBalancedSdfApiService implements SdfApiService {
@Resource
private DeviceManager deviceManager;
private <T> T apply(Function<TMKContext, T> fun) {
TMKContext context = deviceManager.chooseOne();
try {
return fun.apply(context);
} finally {
deviceManager.returnContextToPool(context);
}
}
@Override
public byte[] generateRandom(int len) {
return new byte[0];
return apply(s -> s.getSdfApiAdapter().generateRandom(s.getSessionHandle(), len));
}
@Override
public byte[] genSymKey(KeyAlg alg, Integer keyLen) {
return new byte[0];
return generateRandom(keyLen);
}
@Override
public byte[] genSymKey(KeyAlg alg) {
return new byte[0];
return generateRandom(16);
}
@Override
public byte[] symEncrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
return new byte[0];
byte[] paddingData = null;
switch (padding) {
case NOPadding:
paddingData = data;
break;
case PCKS5Padding:
paddingData = PaddingUtil.PKCS5Padding(data);
break;
case PCKS7Padding:
paddingData = PaddingUtil.PKCS7Padding(data);
break;
}
byte[] finalPaddingData = paddingData;
return apply(s -> s.getSdfApiAdapter()
.externalSymEncrypt(s.getSessionHandle(), key, null, null, finalPaddingData));
}
@Override
@@ -50,6 +72,11 @@ public class LoadBalancedSdfApiService implements SdfApiService {
return new byte[0];
}
@Override
public byte[] symEncrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
return apply(s -> s.getSdfApiAdapter().externalSymEncrypt(s.getSessionHandle(), key, alg, iv, PaddingUtil.PKCS7Padding(data)));
}
@Override
public byte[] symDecrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
return new byte[0];
@@ -60,9 +87,15 @@ public class LoadBalancedSdfApiService implements SdfApiService {
return new byte[0];
}
@Override
public byte[] symDecrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
byte[] decrypt = apply(s -> s.getSdfApiAdapter().externalSymDecrypt(s.getSessionHandle(), key, alg, iv, data));
return PaddingUtil.PKCS7Unpadding(decrypt);
}
@Override
public EccKey genKeyPairEcc() {
return null;
return apply(s -> s.getSdfApiAdapter().generateKeyPairECC(s.getSessionHandle(), AlgId.SGD_SM2_1));
}
@Override
@@ -1,6 +1,8 @@
package com.sunyard.chsm.pool;
import com.sunyard.chsm.sdf.adapter.SdfApiAdapter;
import lombok.Data;
import org.apache.commons.pool2.impl.GenericObjectPool;
/**
* @author liulu
@@ -9,13 +11,13 @@ import lombok.Data;
@Data
public class TMKContext {
private String encTmk;
private String deviceHandle;
private String sessionHandle;
private String keyHandle;
private SdfApiAdapter sdfApiAdapter;
private GenericObjectPool<TMKContext> pool;
}
@@ -50,6 +50,7 @@ public class TMKContextFactory extends BasePooledObjectFactory<TMKContext> {
sdfApiAdapter.getPrivateKeyAccessRight(hs, context.getEncKeyIdx(), context.getAccessCredentials().getBytes());
String hk = sdfApiAdapter.importKeyWithISKECC(hs, context.getEncKeyIdx(), EccCipher.fromHex(context.getEncTmk()));
keyHandle.setKeyHandle(hk);
keyHandle.setSdfApiAdapter(sdfApiAdapter);
log.info("create key handle with isk for {}", context.getIpPort());
return keyHandle;
}