sdf 接口

This commit is contained in:
liulu 2024-11-05 14:02:20 +08:00
parent 87fcf9c0f1
commit 1cf14e0884
5 changed files with 165 additions and 4 deletions

View File

@ -0,0 +1,91 @@
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.utils.gm.BCSM2Utils;
import lombok.SneakyThrows;
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.BigIntegers;
import org.bouncycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.SecureRandom;
/**
* @author liulu
* @since 2024/11/5
*/
public class BcSdfApiAdaptor implements SdfApiAdapter {
private static final DeviceInfo deviceInfo;
static {
deviceInfo = new DeviceInfo();
deviceInfo.setIssuerName("bouncycastle");
deviceInfo.setDeviceName("2356621c1a5976bcd6fe2303e5bbf9a9dddc1c1160a521ac61257b04e12b75df");
deviceInfo.setDeviceSerial("BC00202411051037");
deviceInfo.setDeviceVersion(1);
deviceInfo.setStandardVersion(1);
}
@Override
public String openDevice() {
return "c95a78d9c04a557b7b46dbcb5f36cc665f7446ad73fa75f954220232292f768e";
}
@Override
public boolean closeDevice(String deviceHandle) {
return true;
}
@Override
public String openSession(String deviceHandle) {
return "6975feaffaa35b31b6d4e4555ac403a1ad82f46c3d3ce0ee5005e397d3d07fed";
}
@Override
public void closeSession(String sessionHandle) {
}
@Override
public DeviceInfo getDeviceInfo(String sessionHandle) {
return deviceInfo;
}
@Override
public byte[] generateRandom(String sessionHandle, int uiLength) {
byte[] res = new byte[uiLength];
new SecureRandom().nextBytes(res);
return res;
}
@Override
public EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
BigInteger d = new BigInteger(1, Hex.decode(deviceInfo.getDeviceName()));
ECPoint q = BCSM2Utils.G_POINT.multiply(d).normalize();
return new EccPubKey(256, q.getXCoord().getEncoded(), q.getYCoord().getEncoded());
}
@SneakyThrows
@Override
public EccKey generateKeyPairECC(String sessionHandle, String alg, int uiKeyBits) {
// 生成密钥对
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(new EccPubKey(256, x, y), new EccPriKey(256, d));
}
}

View File

@ -2,6 +2,7 @@ package com.sunyard.chsm.sdf.adapter;
import com.sunyard.chsm.enums.ManufacturerModelEnum;
import com.sunyard.chsm.sdf.context.DeviceContext;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.Assert;
import java.util.Objects;
@ -18,9 +19,9 @@ public class SdfApiAdapterFactory {
Assert.hasText(device.getManufacturerModel(), "设备型号不能为空");
ManufacturerModelEnum model = ManufacturerModelEnum.of(device.getManufacturerModel());
if (Objects.isNull(model)) {
if (Objects.isNull(model) && Objects.equals(BouncyCastleProvider.PROVIDER_NAME, device.getManufacturerModel())) {
// bc adaptor
return null;
return new BcSdfApiAdaptor();
}
switch (model) {
case enc001:

View File

@ -2,6 +2,7 @@ package com.sunyard.chsm.sdf.adapter;
import com.sun.jna.Native;
import com.sun.jna.ptr.PointerByReference;
import com.sunyard.chsm.sdf.context.SunyardAlgId;
import com.sunyard.chsm.sdf.lib.SunyardSdfLibrary;
import java.util.Map;
@ -50,8 +51,7 @@ public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor {
@Override
protected int getAlgId(String alg) {
return 0;
return SunyardAlgId.valueOf(alg).getValue();
}
public static byte[] safeStringBytes(String str) {

View File

@ -0,0 +1,18 @@
package com.sunyard.chsm.sdf.context;
/**
* @author liulu
* @since 2024/11/5
*/
public interface AlgId {
String SGD_SM3 = "SGD_SM3";
String SGD_SM4_CBC = "SGD_SMS4_CBC";
String SGD_SM4_ECB = "SGD_SMS4_ECB";
String SGD_SM4_MAC = "SGD_SMS4_MAC";
String SGD_SM2_1 = "SGD_SM2_1"; // 签名验签
String SGD_SM2_2 = "SGD_SM2_2";
String SGD_SM2_3 = "SGD_SM2_3"; // 加密解密
}

View File

@ -0,0 +1,51 @@
package com.sunyard.chsm.sdf.context;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* @author liulu
* @since 2024/11/5
*/
@Getter
@RequiredArgsConstructor
public enum SunyardAlgId {
// 哈希算法
SGD_SM3(0x00000001),
// 分组算法模式
SGD_ECB(0x01),
SGD_CBC(0x02),
SGD_CFB(0x04),
SGD_OFB(0x08),
SGD_MAC(0x10),
// 分组算法
SGD_SM1(0x00000100),
SGD_SSF33(0x00000200),
SGD_SM4(0x00000400),
SGD_DES(0x00000800),
SGD_3DES(0x00001000),
SGD_IDEA(0x00002000),
SGD_AES(0x00004000),
SGD_SM4_ECB(SGD_SM4.value | SGD_ECB.value),
SGD_SM4_CBC(SGD_SM4.value | SGD_CBC.value),
SGD_SM4_MAC(SGD_SM4.value | SGD_MAC.value),
// 公钥用途
SGD_PK_SIGN(0x0100),
SGD_PK_DH(0x0200),
SGD_PK_ENC(0x0400),
SGD_SM2(0x00020000),
SGD_SM2_1(SGD_SM2.value | SGD_PK_SIGN.value),
SGD_SM2_2(SGD_SM2.value | SGD_PK_DH.value),
SGD_SM2_3(SGD_SM2.value | SGD_PK_ENC.value),
;
private final int value;
}