diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java new file mode 100644 index 0000000..4ce558a --- /dev/null +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java @@ -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)); + } + + +} diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SdfApiAdapterFactory.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SdfApiAdapterFactory.java index f118475..ceb2a8d 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SdfApiAdapterFactory.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SdfApiAdapterFactory.java @@ -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: diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SunyardJnaSdfAdaptor.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SunyardJnaSdfAdaptor.java index e8dcc7a..ce93bf4 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SunyardJnaSdfAdaptor.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/SunyardJnaSdfAdaptor.java @@ -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) { diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/context/AlgId.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/context/AlgId.java new file mode 100644 index 0000000..ce07226 --- /dev/null +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/context/AlgId.java @@ -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"; // 加密解密 +} diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/context/SunyardAlgId.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/context/SunyardAlgId.java new file mode 100644 index 0000000..c298afe --- /dev/null +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/context/SunyardAlgId.java @@ -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; + + +}