This commit is contained in:
liulu 2024-12-11 17:07:34 +08:00
parent 3dc061907f
commit 2250a6234b
8 changed files with 503 additions and 194 deletions

View File

@ -1,186 +1,186 @@
package com.sunyard.chsm.sdf;
import com.sunyard.chsm.enums.AlgMode;
import com.sunyard.chsm.enums.KeyAlg;
import com.sunyard.chsm.enums.KeyCategory;
import com.sunyard.chsm.enums.Padding;
import com.sunyard.chsm.sdf.context.AlgId;
import com.sunyard.chsm.sdf.model.EccKey;
import com.sunyard.chsm.sdf.util.LangUtils;
import com.sunyard.chsm.utils.gm.BCSM2Utils;
import com.sunyard.chsm.utils.gm.BCSM3Utils;
import com.sunyard.chsm.utils.gm.BCSM4Utils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.util.BigIntegers;
import org.springframework.stereotype.Service;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
/**
* 基于 BC 库的国密软算法实现
* 当前实现类的接口返回的对称密钥和私钥认为是明文在上层 Service 进行使用和存储时的加密和解密运算
* <p>
* 主密钥
* - 生成 软随机数项目启动时不存在则自动生成
* - 存储 存储在 SC_PARAM_CONF , KEY mk 的字段值为固定的 48 字节 HEX 格式 96 字节存储
* 16 字节为主密钥值 32 字节为主密钥值使用 SM3 计算的校验值
* - 同步基于数据库进行导入导出和备份恢复多台应用服务器连接同一个数据库无需同步
* - 使用顶层密钥用于保护其他存于数据的密钥
*
* @author liulu Cheney
* @since 2024/10/23
*/
@Slf4j
@Service
public class BCSdfApiService extends AbstractSdfApiService {
public BCSdfApiService() {
super();
}
@Override
public byte[] generateRandom(int len) {
byte[] res = new byte[len];
new SecureRandom().nextBytes(res);
return res;
}
/**
* 生成对称算法密钥
*
* @param alg 算法只支持对称算法
* @param keyLen 密钥长度(bit)只针对密钥长度可变的算法
* 禁止传 null
* @return
*/
@Override
public byte[] genSymKey(KeyAlg alg, Integer keyLen) {
switch (alg) {
case SM4: {
if (null == keyLen || keyLen != BCSM4Utils.DEFAULT_KEY_SIZE) {
throw new IllegalArgumentException("Invalid key length: " + keyLen);
}
try {
return BCSM4Utils.generateKey();
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
throw new RuntimeException("算法实现错误", e);
}
}
default: {
throw new IllegalArgumentException("Unsupported algorithm: " + alg);
}
}
}
@Override
public byte[] symEncrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
return symCalc(Cipher.ENCRYPT_MODE, alg, mode, padding, key, data);
}
@Override
public byte[] symEncrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
return new byte[0];
}
@Override
public byte[] symDecrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
return symCalc(Cipher.DECRYPT_MODE, alg, mode, padding, key, data);
}
@Override
public byte[] symDecrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
return new byte[0];
}
/**
* 对称加解密的统一实现
*
* @param alg 算法只支持对称算法
* @param key 密钥值明文
* @param data 加密时明文数据解密时为密文数据
*/
private byte[] symCalc(int cipherMode, KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
if (alg.getCategory() != KeyCategory.SYM_KEY) {
throw new IllegalArgumentException("Must SYM_KEY, unsupported algorithm: " + alg);
}
// 算法
String algName = null;
if (alg == KeyAlg.SM4) {
algName = "SM4/";
} else {
throw new IllegalArgumentException("Unsupported algorithm: " + alg);
}
// 算法轮模式
algName += mode.getCode() + "/";
// 填充模式
algName += padding.getCode();
Cipher cipher = null;
try {
cipher = BCSM4Utils.generateECBCipher(algName, cipherMode, key);
return cipher.doFinal(data);
} catch (IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | InvalidKeyException e) {
throw new RuntimeException("算法执行错误", e);
}
}
@SneakyThrows
@Override
public EccKey genKeyPairEcc() {
// 生成密钥对
KeyPair keyPair = BCSM2Utils.generateKeyPair();
BCECPublicKey pubKey = (BCECPublicKey) keyPair.getPublic();
BCECPrivateKey priKey = (BCECPrivateKey) keyPair.getPrivate();
byte[] x = pubKey.getQ().getXCoord().getEncoded();
byte[] y = pubKey.getQ().getYCoord().getEncoded();
byte[] d = BigIntegers.asUnsignedByteArray(32, priKey.getD());
return new EccKey(LangUtils.merge(x, y), d);
}
@Override
public byte[] calculateMAC(byte[] symKey, byte[] pucIv, byte[] pucData) {
return new byte[0];
}
@Override
public byte[] hmac(byte[] key, byte[] srcData) {
return BCSM3Utils.hmac(key, srcData);
}
@Override
public byte[] hash(byte[] pucData) {
return BCSM3Utils.hash(pucData);
}
@Override
public byte[] encryptByTMK(byte[] data) {
return data;
}
@Override
public byte[] decryptByTMK(byte[] data) {
return data;
}
}
//package com.sunyard.chsm.sdf;
//
//
//import com.sunyard.chsm.enums.AlgMode;
//import com.sunyard.chsm.enums.KeyAlg;
//import com.sunyard.chsm.enums.KeyCategory;
//import com.sunyard.chsm.enums.Padding;
//import com.sunyard.chsm.sdf.context.AlgId;
//import com.sunyard.chsm.sdf.model.EccKey;
//import com.sunyard.chsm.sdf.util.LangUtils;
//import com.sunyard.chsm.utils.gm.BCSM2Utils;
//import com.sunyard.chsm.utils.gm.BCSM3Utils;
//import com.sunyard.chsm.utils.gm.BCSM4Utils;
//import lombok.SneakyThrows;
//import lombok.extern.slf4j.Slf4j;
//import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
//import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
//import org.bouncycastle.util.BigIntegers;
//import org.springframework.stereotype.Service;
//
//import javax.crypto.BadPaddingException;
//import javax.crypto.Cipher;
//import javax.crypto.IllegalBlockSizeException;
//import javax.crypto.NoSuchPaddingException;
//import java.security.InvalidKeyException;
//import java.security.KeyPair;
//import java.security.NoSuchAlgorithmException;
//import java.security.NoSuchProviderException;
//import java.security.SecureRandom;
//
//
///**
// * 基于 BC 库的国密软算法实现
// * 当前实现类的接口返回的对称密钥和私钥认为是明文在上层 Service 进行使用和存储时的加密和解密运算
// * <p>
// * 主密钥
// * - 生成 软随机数项目启动时不存在则自动生成
// * - 存储 存储在 SC_PARAM_CONF , KEY mk 的字段值为固定的 48 字节 HEX 格式 96 字节存储
// * 16 字节为主密钥值 32 字节为主密钥值使用 SM3 计算的校验值
// * - 同步基于数据库进行导入导出和备份恢复多台应用服务器连接同一个数据库无需同步
// * - 使用顶层密钥用于保护其他存于数据的密钥
// *
// * @author liulu Cheney
// * @since 2024/10/23
// */
//@Slf4j
//@Service
//public class BCSdfApiService extends AbstractSdfApiService {
//
// public BCSdfApiService() {
// super();
// }
//
// @Override
// public byte[] generateRandom(int len) {
// byte[] res = new byte[len];
// new SecureRandom().nextBytes(res);
// return res;
// }
//
//
// /**
// * 生成对称算法密钥
// *
// * @param alg 算法只支持对称算法
// * @param keyLen 密钥长度(bit)只针对密钥长度可变的算法
// * 禁止传 null
// * @return
// */
// @Override
// public byte[] genSymKey(KeyAlg alg, Integer keyLen) {
// switch (alg) {
// case SM4: {
// if (null == keyLen || keyLen != BCSM4Utils.DEFAULT_KEY_SIZE) {
// throw new IllegalArgumentException("Invalid key length: " + keyLen);
// }
// try {
// return BCSM4Utils.generateKey();
// } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
// throw new RuntimeException("算法实现错误", e);
// }
// }
// default: {
// throw new IllegalArgumentException("Unsupported algorithm: " + alg);
// }
// }
// }
//
// @Override
// public byte[] symEncrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
// return symCalc(Cipher.ENCRYPT_MODE, alg, mode, padding, key, data);
// }
//
// @Override
// public byte[] symEncrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
// return new byte[0];
// }
//
//
// @Override
// public byte[] symDecrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
// return symCalc(Cipher.DECRYPT_MODE, alg, mode, padding, key, data);
// }
//
// @Override
// public byte[] symDecrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
// return new byte[0];
// }
//
//
// /**
// * 对称加解密的统一实现
// *
// * @param alg 算法只支持对称算法
// * @param key 密钥值明文
// * @param data 加密时明文数据解密时为密文数据
// */
// private byte[] symCalc(int cipherMode, KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
// if (alg.getCategory() != KeyCategory.SYM_KEY) {
// throw new IllegalArgumentException("Must SYM_KEY, unsupported algorithm: " + alg);
// }
//
// // 算法
// String algName = null;
// if (alg == KeyAlg.SM4) {
// algName = "SM4/";
// } else {
// throw new IllegalArgumentException("Unsupported algorithm: " + alg);
// }
//
// // 算法轮模式
// algName += mode.getCode() + "/";
//
// // 填充模式
// algName += padding.getCode();
//
//
// Cipher cipher = null;
// try {
// cipher = BCSM4Utils.generateECBCipher(algName, cipherMode, key);
// return cipher.doFinal(data);
// } catch (IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | InvalidKeyException e) {
// throw new RuntimeException("算法执行错误", e);
// }
// }
//
// @SneakyThrows
// @Override
// public EccKey genKeyPairEcc() {
// // 生成密钥对
// KeyPair keyPair = BCSM2Utils.generateKeyPair();
// BCECPublicKey pubKey = (BCECPublicKey) keyPair.getPublic();
// BCECPrivateKey priKey = (BCECPrivateKey) keyPair.getPrivate();
// byte[] x = pubKey.getQ().getXCoord().getEncoded();
// byte[] y = pubKey.getQ().getYCoord().getEncoded();
// byte[] d = BigIntegers.asUnsignedByteArray(32, priKey.getD());
// return new EccKey(LangUtils.merge(x, y), d);
// }
//
//
// @Override
// public byte[] calculateMAC(byte[] symKey, byte[] pucIv, byte[] pucData) {
// return new byte[0];
// }
//
// @Override
// public byte[] hmac(byte[] key, byte[] srcData) {
// return BCSM3Utils.hmac(key, srcData);
// }
//
// @Override
// public byte[] hash(byte[] pucData) {
// return BCSM3Utils.hash(pucData);
// }
//
// @Override
// public byte[] encryptByTMK(byte[] data) {
// return data;
// }
//
// @Override
// public byte[] decryptByTMK(byte[] data) {
// return data;
// }
//
//}

View File

@ -213,4 +213,34 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
Assert.notNull(key, "密钥句柄不存在");
return key;
}
@Override
public byte[] calculateMAC(String sessionHandle, String keyHandle, AlgId uiAlg, byte[] pucIv, byte[] pucData) {
return new byte[0];
}
@Override
public byte[] calculateMAC(String sessionHandle, byte[] symKey, AlgId uiAlg, byte[] pucIv, byte[] pucData) {
return new byte[0];
}
@Override
public int hashInit(String sessionHandle, AlgId alg, EccPubKey pucPublicKey, byte[] pucID) {
return 0;
}
@Override
public int hashUpdate(String sessionHandle, byte[] pucData) {
return 0;
}
@Override
public byte[] hashFinish(String sessionHandle) {
return new byte[0];
}
@Override
public byte[] hashOperation(String sessionHandle, AlgId alg, EccPubKey pucPublicKey, byte[] pucID, byte[] pucData) {
return new byte[0];
}
}

View File

@ -257,4 +257,70 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
sdfLibrary.SDF_DestroyKey(hSessionHandle, hKeyHandle);
return pucData;
}
@Override
public byte[] calculateMAC(String sessionHandle, String keyHandle, AlgId uiAlg, byte[] pucIv, byte[] pucData) {
Pointer hSessionHandle = getSessionHandle(sessionHandle);
Pointer hKeyHandle = getKeyHandle(keyHandle);
int uiMacLength = pucData.length;
byte[] pucMac = new byte[uiMacLength];
IntByReference puiLength = new IntByReference();
sdfLibrary.SDF_CalculateMAC(hSessionHandle, hKeyHandle, getAlgId(uiAlg), pucIv, pucData, uiMacLength, pucMac, puiLength);
return pucMac;
}
@Override
public byte[] calculateMAC(String sessionHandle, byte[] symKey, AlgId uiAlg, byte[] pucIv, byte[] pucData) {
PointerByReference phKeyHandle = new PointerByReference();
Pointer hSessionHandle = getSessionHandle(sessionHandle);
int length = symKey.length;
// 导入会话密钥
sdfLibrary.SDF_ImportKey(hSessionHandle, symKey, length, phKeyHandle);
int uiMacLength = pucData.length;
byte[] pucMac = new byte[uiMacLength];
Pointer hKeyHandle = phKeyHandle.getValue();
IntByReference puiLength = new IntByReference();
sdfLibrary.SDF_CalculateMAC(hSessionHandle, hKeyHandle, getAlgId(uiAlg), pucIv, pucData, uiMacLength, pucMac, puiLength);
// 销毁会话密钥
sdfLibrary.SDF_DestroyKey(hSessionHandle, hKeyHandle);
return pucMac;
}
@Override
public int hashInit(String sessionHandle, AlgId alg, EccPubKey pucPublicKey, byte[] pucID) {
Pointer hSessionHandle = getSessionHandle(sessionHandle);
byte[] pubPub = pucPublicKey == null ? null : pucPublicKey.toSdfData();
return sdfLibrary.SDF_HashInit(hSessionHandle, getAlgId(AlgId.SGD_SM3), pubPub, pucID, pucID.length);
}
@Override
public int hashUpdate(String sessionHandle, byte[] pucData) {
Pointer hSessionHandle = getSessionHandle(sessionHandle);
return sdfLibrary.SDF_HashUpdate(hSessionHandle, pucData, pucData.length);
}
@Override
public byte[] hashFinish(String sessionHandle) {
Pointer hSessionHandle = getSessionHandle(sessionHandle);
byte[] pucHash = new byte[32];
IntByReference puiLength = new IntByReference();
sdfLibrary.SDF_HashFinal(hSessionHandle, pucHash, puiLength);
return pucHash;
}
@Override
public byte[] hashOperation(String sessionHandle, AlgId alg, EccPubKey pucPublicKey, byte[] pucID, byte[] pucData) {
Pointer hSessionHandle = getSessionHandle(sessionHandle);
byte[] pubPub = pucPublicKey == null ? null : pucPublicKey.toSdfData();
sdfLibrary.SDF_HashInit(hSessionHandle, getAlgId(AlgId.SGD_SM3), pubPub, pucID, pucID.length);
sdfLibrary.SDF_HashUpdate(hSessionHandle, pucData, pucData.length);
byte[] pucHash = new byte[32];
IntByReference puiLength = new IntByReference();
sdfLibrary.SDF_HashFinal(hSessionHandle, pucHash, puiLength);
return pucHash;
}
}

View File

@ -135,4 +135,47 @@ public interface SdfApiAdapter {
byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData);
byte[] externalSymDecrypt(String sessionHandle, byte[] symKey, AlgId alg, byte[] pucIv, byte[] pucEncData);
/**
* @param sessionHandle 与设备建立的会话句柄
* @param keyHandle 指定的密钥句柄
* @param uiAlg 算法标识指定MAC算法 SGD_SMS4_MAC
* @param pucIv IV数据
* @param pucData 数据明文
* @return MAC值
*/
byte[] calculateMAC(String sessionHandle, String keyHandle, AlgId uiAlg, byte[] pucIv, byte[] pucData);
byte[] calculateMAC(String sessionHandle, byte[] symKey, AlgId uiAlg, byte[] pucIv, byte[] pucData);
/**
* 杂凑运算初始化
*
* @param sessionHandle 与设备建立的会话句柄
* @param alg 当前杂凑算法标识 SGD_SM3
* @param pucPublicKey 签名者公钥当uiAlgID为SGD_SM3时有效
* @param pucID 签名者的ID值当uiAlgID为SGD_SM3时有效
* @return 0 成功; 非0 失败,返回错误代码
*/
int hashInit(String sessionHandle, AlgId alg, EccPubKey pucPublicKey, byte[] pucID);
/**
* 多包杂凑运算
*
* @param sessionHandle sessionHandle
* @param pucData 数据明文
* @return 0 成功; 非0 失败,返回错误代码
*/
int hashUpdate(String sessionHandle, byte[] pucData);
/**
* 杂凑运算结束
*
* @param sessionHandle 与设备建立的会话句柄
* @return 杂凑数据
*/
byte[] hashFinish(String sessionHandle);
byte[] hashOperation(String sessionHandle, AlgId alg, EccPubKey pucPublicKey, byte[] pucID, byte[] pucData);
}

View File

@ -283,7 +283,7 @@ public interface SdfLibrary extends Library {
* @param pucIDlength 签名者ID的长度
* @return int 响应码
*/
int SDF_HashInit(Pointer phSessionHandle, int uiAlgID, byte[] pucPublicKey, String pucID, int pucIDlength);
int SDF_HashInit(Pointer phSessionHandle, int uiAlgID, byte[] pucPublicKey, byte[] pucID, int pucIDlength);
/**
* 多包杂凑运算

View File

@ -24,7 +24,7 @@ public class EccPriKey {
public static EccPriKey fromBytes(byte[] priKey) {
Assert.notNull(priKey, "公钥数据不能为null");
if (Objects.equals(priKey.length, 132)) {
if (Objects.equals(priKey.length, 68)) {
// 00010000
priKey = Arrays.copyOfRange(priKey, 4, priKey.length);
}

View File

@ -0,0 +1,166 @@
package com.sunyard.chsm.sdf;
import com.sunyard.chsm.enums.AlgMode;
import com.sunyard.chsm.enums.DeviceTmkStatus;
import com.sunyard.chsm.enums.KeyAlg;
import com.sunyard.chsm.enums.Padding;
import com.sunyard.chsm.mapper.SpDeviceMapper;
import com.sunyard.chsm.model.dto.DeviceCheckRes;
import com.sunyard.chsm.model.entity.Device;
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.AlgId;
import com.sunyard.chsm.sdf.model.DeviceInfo;
import com.sunyard.chsm.sdf.model.EccCipher;
import com.sunyard.chsm.sdf.model.EccKey;
import com.sunyard.chsm.service.TmkService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @author liulu
* @since 2024/12/11
*/
@Service
@RequiredArgsConstructor
public class SingleSdfApiService implements SdfApiService, InitializingBean {
private String tmkHandle;
private String sessionHandle;
private SdfApiAdapter sdfApiAdapter;
private final TmkService tmkService;
private final SpDeviceMapper spDeviceMapper;
@Override
public byte[] generateRandom(int len) {
return new byte[0];
}
@Override
public byte[] genSymKey(KeyAlg alg, Integer keyLen) {
return new byte[0];
}
@Override
public byte[] genSymKey(KeyAlg alg) {
return new byte[0];
}
@Override
public byte[] symEncrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
return new byte[0];
}
@Override
public byte[] symEncrypt(KeyAlg alg, byte[] key, byte[] data) {
return new byte[0];
}
@Override
public byte[] symEncrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
return new byte[0];
}
@Override
public byte[] symDecrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
return new byte[0];
}
@Override
public byte[] symDecrypt(KeyAlg alg, byte[] key, byte[] data) {
return new byte[0];
}
@Override
public byte[] symDecrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
return new byte[0];
}
@Override
public EccKey genKeyPairEcc() {
return null;
}
@Override
public byte[] calculateMAC(byte[] symKey, byte[] pucIv, byte[] pucData) {
return new byte[0];
}
@Override
public byte[] hmac(byte[] key, byte[] srcData) {
return new byte[0];
}
@Override
public byte[] hash(byte[] pucData) {
return new byte[0];
}
@Override
public byte[] encryptByTMK(byte[] data) {
return new byte[0];
}
@Override
public byte[] decryptByTMK(byte[] data) {
return new byte[0];
}
private void changeDevice(boolean tmkInit) {
DeviceTmkStatus status = tmkInit ? DeviceTmkStatus.finished : DeviceTmkStatus.available;
Device device = spDeviceMapper.selectOneByStatus(status);
if (Objects.nonNull(device)) {
DeviceCheckRes checkRes = tmkService.checkDevice(device);
if (!checkRes.isHasError()) {
this.sdfApiAdapter = checkRes.getSdfApiAdapter();
String hd = sdfApiAdapter.openDevice();
this.sessionHandle = sdfApiAdapter.openSession(hd);
if (tmkInit) {
sdfApiAdapter.getPrivateKeyAccessRight(sessionHandle, device.getEncKeyIdx(), device.getAccessCredentials().getBytes());
this.tmkHandle = sdfApiAdapter.importKeyWithISKECC(sessionHandle, device.getEncKeyIdx(), EccCipher.fromHex(device.getEncTmk()));
}
return;
}
}
if (tmkService.isEnableSoftDevice()) {
this.sdfApiAdapter = SdfApiAdapterFactory.getBcAdapter();
this.sessionHandle = sdfApiAdapter.openSession("");
if (tmkInit) {
byte[] encTmk = tmkService.getSoftDeviceEncTmk();
this.tmkHandle = sdfApiAdapter.importKeyWithISKECC(sessionHandle, device.getEncKeyIdx(), EccCipher.fromBytes(encTmk));
}
}
}
@Override
public void afterPropertiesSet() throws Exception {
Executors.newSingleThreadScheduledExecutor()
.scheduleWithFixedDelay(() -> {
boolean tmkInit = tmkService.isTmkInit();
if (sdfApiAdapter != null) {
if (sdfApiAdapter instanceof BcSdfApiAdaptor) {
changeDevice(tmkInit);
return;
}
if (tmkInit && StringUtils.isEmpty(tmkHandle)) {
changeDevice(tmkInit);
return;
}
try {
DeviceInfo deviceInfo = sdfApiAdapter.getDeviceInfo(sessionHandle);
} catch (Exception ex) {
changeDevice(tmkInit);
}
} else {
changeDevice(tmkInit);
}
}, 0L, 5L, TimeUnit.MINUTES);
}
}

View File

@ -7,7 +7,9 @@ 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 com.sunyard.chsm.utils.gm.BCSM3Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.function.Function;
@ -17,9 +19,9 @@ import java.util.function.Function;
* @since 2024/12/10
*/
@Slf4j
@Service
public class LoadBalancedSdfApiService implements SdfApiService {
@Resource
private DeviceManager deviceManager;
@ -100,26 +102,28 @@ public class LoadBalancedSdfApiService implements SdfApiService {
@Override
public byte[] calculateMAC(byte[] symKey, byte[] pucIv, byte[] pucData) {
return new byte[0];
return apply(s -> s.getSdfApiAdapter().calculateMAC(s.getSessionHandle(), symKey, AlgId.SGD_SM4_MAC, pucIv, pucData));
}
@Override
public byte[] hmac(byte[] key, byte[] srcData) {
return new byte[0];
return BCSM3Utils.hmac(key, srcData);
}
@Override
public byte[] hash(byte[] pucData) {
return new byte[0];
return apply(s -> s.getSdfApiAdapter().hashOperation(s.getSessionHandle(), AlgId.SGD_SM3, null, null, pucData));
}
@Override
public byte[] encryptByTMK(byte[] data) {
return new byte[0];
byte[] pad = PaddingUtil.PKCS7Unpadding(data);
return apply(s -> s.getSdfApiAdapter().symEncrypt(s.getSessionHandle(), s.getKeyHandle(), AlgId.SGD_SM4_CBC, new byte[8], pad));
}
@Override
public byte[] decryptByTMK(byte[] data) {
return new byte[0];
byte[] decrypt = apply(s -> s.getSdfApiAdapter().symDecrypt(s.getSessionHandle(), s.getKeyHandle(), AlgId.SGD_SM4_CBC, new byte[8], data));
return PaddingUtil.PKCS7Unpadding(decrypt);
}
}