sdf api
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user