Explorar o código

修正sm2前后端签名验签与工具通用

xusl hai 1 ano
pai
achega
d02faaa320

+ 14 - 7
backend/src/main/java/com/jiayue/ssi/util/SM2CryptUtils.java

@@ -1,10 +1,8 @@
 package com.jiayue.ssi.util;
 
-import cn.hutool.core.codec.Base64;
 import cn.hutool.core.util.HexUtil;
 import cn.hutool.crypto.BCUtil;
 import cn.hutool.crypto.ECKeyUtil;
-import cn.hutool.crypto.SecureUtil;
 import cn.hutool.crypto.asymmetric.KeyType;
 import cn.hutool.crypto.asymmetric.SM2;
 import cn.hutool.crypto.SmUtil;
@@ -88,6 +86,8 @@ public class SM2CryptUtils {
      */
     public static boolean verifySign(String publicKey, String content, String sign) {
         SM2 sm2 = new SM2(null, publicKey);
+        sm2.setMode(SM2Engine.Mode.C1C3C2);
+        sm2.setEncoding(new PlainDSAEncoding());
         boolean verify = sm2.verifyHex(HexUtil.encodeHexStr(content), sign);
         return verify;
     }
@@ -100,17 +100,24 @@ public class SM2CryptUtils {
      */
     public static String sign(String privateKey,String content) {
         SM2 sm2 = new SM2(privateKey, null);
+        sm2.setEncoding(new PlainDSAEncoding());
         String sign = sm2.signHex(HexUtil.encodeHexStr(content));
         return sign;
     }
 
     public static void main(String[] args) {
-        String a = encrypt("ttttt", SecretKeyConstants.SERVER_PUBLIC_KEY);
-        System.out.println(a);
-        String b = decrypt(a, SecretKeyConstants.SERVER_PRIVATE_KEY);
+//        String a = encrypt("ttttt", SecretKeyConstants.SERVER_PUBLIC_KEY);
+//        System.out.println(a);
+//        String b = decrypt(a, SecretKeyConstants.SERVER_PRIVATE_KEY);
+//        System.out.println(b);
+
+//        String base = "1276559e024c4f9b5c46f662ac51d69779bf4f9d278ef5215fbc36b5e4fc6da894545003694e4e71a01592edef940d6d13e88f8a09a9d91bdb214990b36ea34e";
+//        System.out.println(verifySign(SecretKeyConstants.SERVER_PUBLIC_KEY,"测试",base));
+
+        String b = encrypt("测试的","0460ff8c8c306fe62f6f9d11c5c82c30d10bbbc703da094e423072cac7dc663c97fad52eccb34f311f47a07f280de157ba4f2aa659cabe749121384b9376ea2ed2");
         System.out.println(b);
+//        String a = decrypt("ABC759C8C9FD55DFC92990580057A528073B0D498EFA0EDECE70DC55BF2DE0CCA1F5EC7E6F1FBD13586C3BA12F2A2795B82312A2FCFAA3A95323BAEE8690E4BD0E38F7C41024720098DFA16F2A7DCF27CD3C4750106A1C9B9A20FEA54E1C709D0AD2D3217152","E33C8730110B13828F2B04122831E62E71E4E990C7D277C4FA37EB68DCE25E33");
+//        System.out.println(a);
 
-        String base = "aEsva0zDHECg47P8SuPzmw==";
-        System.out.println(SecureUtil.aes(Base64.decode(base)).encrypt("ttttt"));
     }
 }

+ 75 - 0
backend/src/test/java/com/jiayue/ssi/service/BcSm2Util.java

@@ -0,0 +1,75 @@
+package com.jiayue.ssi.service;
+
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.BCUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.SmUtil;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.SM2;
+import com.jiayue.ssi.util.SM2CryptUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.bouncycastle.asn1.gm.GMNamedCurves;
+import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.engines.SM2Engine;
+import org.bouncycastle.crypto.params.*;
+import org.bouncycastle.crypto.signers.PlainDSAEncoding;
+import org.bouncycastle.crypto.signers.SM2Signer;
+import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
+import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.bouncycastle.util.Strings;
+import org.bouncycastle.util.encoders.Hex;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Base64;
+
+/**
+*
+*
+* @author xsl
+* @since 2023/08/08
+*/
+@Slf4j
+public class BcSm2Util {
+    public static void main(String[] args) {
+        //需要加密的明文
+        String text = "测试";
+        String pv = "6155d63ee27cbeca07f3e40c4f8856f1be8119fcbda1aadc7e0e595e52bad7bd";
+        String pu = "041967638ca43d4577d8dba166bff4437fde944270101f398a95b846ec2f8177d09f8abc5d62b6cd2c7216274d7abe0c8e04b0bb691207a32dd2e12d6bd2798672";
+        //创建sm2 对象
+        SM2 sm2 = SmUtil.sm2(pv,pu);
+        //这里会自动生成对应的随机秘钥对 , 注意! 这里一定要强转,才能得到对应有效的秘钥信息
+//        byte[] privateKey = BCUtil.encodeECPrivateKey(sm2.getPrivateKey());
+//        //这里公钥不压缩  公钥的第一个字节用于表示是否压缩  可以不要
+//        byte[] publicKey = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false);
+        //这里得到的 压缩后的公钥   ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(true);
+        // byte[] publicKeyEc = BCUtil.encodeECPublicKey(sm2.getPublicKey());
+        //打印当前的公私秘钥
+//        System.out.println("私钥: " + HexUtil.encodeHexStr(pv.getBytes()));
+//        System.out.println("公钥: " + HexUtil.encodeHexStr(pu.getBytes()));
+        //得到明文对应的字节数组
+        byte[] dateBytes = text.getBytes();
+        System.out.println("数据: " + HexUtil.encodeHexStr(dateBytes));
+        //这里需要手动设置,sm2 对象的默认值与我们期望的不一致
+        sm2.setMode(SM2Engine.Mode.C1C3C2);
+        sm2.setEncoding(new PlainDSAEncoding());
+        //计算签名
+        byte[] sign = sm2.sign(dateBytes, null);
+        System.out.println("签名: " + HexUtil.encodeHexStr(sign));
+        // 校验  验签
+        boolean verify = sm2.verify(dateBytes, sign);
+        System.out.println(verify);
+
+
+        String signold = SM2CryptUtils.sign(pv,text);
+        System.out.println(signold);
+
+    }
+}

+ 85 - 0
backend/src/test/java/com/jiayue/ssi/service/KeyUtils.java

@@ -0,0 +1,85 @@
+package com.jiayue.ssi.service;/**
+*
+*
+* @author xsl
+* @since 2023/08/08
+*/
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.security.*;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+
+/**
+ * @author lihongxu6
+ * @version 1.0
+ * @className KeyUtils
+ * @description TODO
+ * @date 2021-01-13 23:27
+ */
+public class KeyUtils {
+    /**
+     * 生成国密公私钥对
+     * <p>
+     * <code>String[0]</code> 公钥
+     * <p>
+     * <code>String[1]</code> 私钥
+     *
+     * @return
+     * @throws Exception
+     */
+    public static String[] generateSmKey() throws Exception {
+        KeyPairGenerator keyPairGenerator = null;
+        SecureRandom secureRandom = new SecureRandom();
+        ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
+        keyPairGenerator = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
+        keyPairGenerator.initialize(sm2Spec);
+        keyPairGenerator.initialize(sm2Spec, secureRandom);
+        KeyPair keyPair = keyPairGenerator.generateKeyPair();
+        PrivateKey privateKey = keyPair.getPrivate();
+        PublicKey publicKey = keyPair.getPublic();
+        String[] result = {
+                new String(Base64.getEncoder().encode(publicKey.getEncoded()))
+                , new String(Base64.getEncoder().encode(privateKey.getEncoded()))
+        };
+        return result;
+    }
+    /**
+     * 将Base64转码的公钥串,转化为公钥对象
+     *
+     * @param publicKey
+     * @return
+     */
+    public static PublicKey createPublicKey(String publicKey) {
+        PublicKey publickey = null;
+        try{
+            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
+            KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());
+            publickey = keyFactory.generatePublic(publicKeySpec);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return publickey;
+    }
+
+    /**
+     * 将Base64转码的私钥串,转化为私钥对象
+     *
+     * @param privateKey
+     * @return
+     */
+    public static PrivateKey createPrivateKey(String privateKey) {
+        PrivateKey publickey = null;
+        try{
+            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
+            KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());
+            publickey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return publickey;
+    }
+}

+ 412 - 0
backend/src/test/java/com/jiayue/ssi/service/Sm2Test.java

@@ -0,0 +1,412 @@
+package com.jiayue.ssi.service;
+
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.SM2;
+import com.jiayue.ssi.util.SM2CryptUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.bouncycastle.asn1.gm.GMNamedCurves;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoException;
+import org.bouncycastle.crypto.engines.SM2Engine;
+import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
+import org.bouncycastle.crypto.params.*;
+import org.bouncycastle.crypto.signers.SM2Signer;
+import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
+import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
+import org.bouncycastle.jce.ECNamedCurveTable;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.bouncycastle.jce.spec.ECPrivateKeySpec;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.util.Strings;
+import org.bouncycastle.util.encoders.Hex;
+
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+
+
+/**
+ *
+ *
+ * @author xsl
+ * @since 2023/08/07
+ */
+@Slf4j
+public class Sm2Test {
+
+    /**
+     * 生成SM2公私钥对
+     * @return
+     */
+    private static AsymmetricCipherKeyPair genKeyPair0() {
+        //获取一条SM2曲线参数
+        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
+
+        //构造domain参数
+        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
+                sm2ECParameters.getG(), sm2ECParameters.getN());
+
+        //1.创建密钥生成器
+        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
+
+        //2.初始化生成器,带上随机数
+        try {
+            keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
+        } catch (NoSuchAlgorithmException e) {
+            log.error("生成公私钥对时出现异常:", e);
+//            e.printStackTrace();
+        }
+
+        //3.生成密钥对
+        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
+        return asymmetricCipherKeyPair;
+    }
+
+    /**
+     * 私钥签名
+     * @param privateKey    私钥
+     * @param content       待签名内容
+     * @return
+     */
+    public static String sign(String privateKey, String content) throws CryptoException {
+        //待签名内容转为字节数组
+        byte[] message = Hex.decode(content);
+
+        //获取一条SM2曲线参数
+        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
+        //构造domain参数
+        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
+                sm2ECParameters.getG(), sm2ECParameters.getN());
+
+        BigInteger privateKeyD = new BigInteger(privateKey, 16);
+        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
+
+        //创建签名实例
+        SM2Signer sm2Signer = new SM2Signer();
+
+        //初始化签名实例,带上ID,国密的要求,ID默认值:1234567812345678
+        try {
+            sm2Signer.init(true, new ParametersWithID(new ParametersWithRandom(privateKeyParameters, SecureRandom.getInstance("SHA1PRNG")), Strings.toByteArray("31323334353637383132333435363738")));
+        } catch (NoSuchAlgorithmException e) {
+            log.error("签名时出现异常:", e);
+        }
+        sm2Signer.update(message, 0, message.length);
+        //生成签名,签名分为两部分r和s,分别对应索引0和1的数组
+        byte[] signBytes = sm2Signer.generateSignature();
+
+        String sign = Hex.toHexString(signBytes);
+
+        return sign;
+    }
+
+    /**
+     * 将R或者S修正为固定字节数
+     * @param rs
+     * @return
+     */
+    private static byte[] modifyRSFixedBytes(byte[] rs) {
+        int length = rs.length;
+        int fixedLength = 32;
+        byte[] result = new byte[fixedLength];
+        if (length < 32) {
+            System.arraycopy(rs, 0, result, fixedLength - length, length);
+        } else {
+            System.arraycopy(rs, length - fixedLength, result, 0, fixedLength);
+        }
+        return result;
+    }
+
+    /**
+     * 验证签名
+     * @param publicKey     公钥
+     * @param content       待签名内容
+     * @param sign          签名值
+     * @return
+     */
+    public static boolean verify(String publicKey, String content, String sign) {
+        //待签名内容
+        byte[] message = Hex.decode(content);
+        byte[] signData = Hex.decode(sign);
+
+        // 获取一条SM2曲线参数
+        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
+        // 构造domain参数
+        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
+                sm2ECParameters.getG(),
+                sm2ECParameters.getN());
+        //提取公钥点
+        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));
+        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
+        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
+        //创建签名实例
+        SM2Signer sm2Signer = new SM2Signer();
+        ParametersWithID parametersWithID = new ParametersWithID(publicKeyParameters, Strings.toByteArray("31323334353637383132333435363738"));
+        sm2Signer.init(false, parametersWithID);
+        sm2Signer.update(message, 0, message.length);
+        //验证签名结果
+        boolean verify = sm2Signer.verifySignature(signData);
+        return verify;
+    }
+
+    /**
+     * SM2加密算法
+     * @param publicKey     公钥
+     * @param data          数据
+     * @return
+     */
+    public static String encrypt(String publicKey, String data){
+        // 获取一条SM2曲线参数
+        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
+        // 构造domain参数
+        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
+                sm2ECParameters.getG(),
+                sm2ECParameters.getN());
+        //提取公钥点
+        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));
+        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
+        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
+        SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2;
+
+        SM2Engine sm2Engine = new SM2Engine(mode);
+        sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));
+
+        byte[] arrayOfBytes = null;
+        try {
+            byte[] in = data.getBytes("utf-8");
+            arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
+        } catch (Exception e) {
+            log.error("SM2加密时出现异常:", e);
+        }
+        return Hex.toHexString(arrayOfBytes);
+    }
+
+    /**
+     * SM2加密算法
+     * @param publicKey     公钥
+     * @param data          明文数据
+     * @return
+     */
+    public static String encrypt(PublicKey publicKey, String data) {
+
+        ECPublicKeyParameters ecPublicKeyParameters = null;
+        if (publicKey instanceof BCECPublicKey) {
+            BCECPublicKey bcecPublicKey = (BCECPublicKey) publicKey;
+            ECParameterSpec ecParameterSpec = bcecPublicKey.getParameters();
+            ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
+                    ecParameterSpec.getG(), ecParameterSpec.getN());
+            ecPublicKeyParameters = new ECPublicKeyParameters(bcecPublicKey.getQ(), ecDomainParameters);
+        }
+
+        SM2Engine sm2Engine = new SM2Engine();
+        sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));
+
+        byte[] arrayOfBytes = null;
+        try {
+            byte[] in = data.getBytes("utf-8");
+            arrayOfBytes = sm2Engine.processBlock(in,0, in.length);
+        } catch (Exception e) {
+            log.error("SM2加密时出现异常:", e);
+        }
+        return Hex.toHexString(arrayOfBytes);
+    }
+
+    /**
+     * SM2解密算法
+     * @param privateKey    私钥
+     * @param cipherData    密文数据
+     * @return
+     */
+    public static String decrypt(String privateKey, String cipherData) {
+        byte[] cipherDataByte = Hex.decode(cipherData);
+
+        //获取一条SM2曲线参数
+        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
+        //构造domain参数
+        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
+                sm2ECParameters.getG(), sm2ECParameters.getN());
+
+        BigInteger privateKeyD = new BigInteger(privateKey, 16);
+        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
+        SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2;
+        SM2Engine sm2Engine = new SM2Engine(mode);
+        sm2Engine.init(false, privateKeyParameters);
+
+        String result = null;
+        try {
+            byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
+            return new String(arrayOfBytes, "utf-8");
+        } catch (Exception e) {
+            log.error("SM2解密时出现异常:", e);
+        }
+        return result;
+
+    }
+
+    /**
+     * SM2解密算法
+     * @param privateKey        私钥
+     * @param cipherData        密文数据
+     * @return
+     */
+    public static String decrypt(PrivateKey privateKey, String cipherData) {
+        byte[] cipherDataByte = Hex.decode(cipherData);
+
+        BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) privateKey;
+        ECParameterSpec ecParameterSpec = bcecPrivateKey.getParameters();
+
+        ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
+                ecParameterSpec.getG(), ecParameterSpec.getN());
+
+        ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(),
+                ecDomainParameters);
+
+        SM2Engine sm2Engine = new SM2Engine();
+        sm2Engine.init(false, ecPrivateKeyParameters);
+
+        String result = null;
+        try {
+            byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
+            return new String(arrayOfBytes, "utf-8");
+        } catch (Exception e) {
+            log.error("SM2解密时出现异常:", e);
+        }
+        return result;
+    }
+
+    /**
+     * 将未压缩公钥压缩成压缩公钥
+     * 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
+     * @param pubKey    未压缩公钥(16进制,不要带头部04)
+     * @return
+     */
+    public static String compressPubKey(String pubKey) {
+        pubKey = "04" + pubKey;    //将未压缩公钥加上未压缩标识.
+        // 获取一条SM2曲线参数
+        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
+        //提取公钥点
+        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(pubKey));
+        String compressPubKey = Hex.toHexString(pukPoint.getEncoded(Boolean.TRUE));
+
+        return compressPubKey;
+    }
+
+    /**
+     * 将压缩的公钥解压为非压缩公钥
+     * @param compressKey   压缩公钥
+     * @return
+     */
+    public static String unCompressPubKey(String compressKey) {
+        // 获取一条SM2曲线参数
+        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
+        //提取公钥点
+        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(compressKey));
+        String pubKey = Hex.toHexString(pukPoint.getEncoded(Boolean.FALSE));
+        //去掉前面的04   (04的时候,可以去掉前面的04)
+        pubKey = pubKey.substring(2);
+        return pubKey;
+    }
+
+    public static void main(String[] args) throws Exception{
+
+        String priKey = "6155d63ee27cbeca07f3e40c4f8856f1be8119fcbda1aadc7e0e595e52bad7bd";
+        System.out.println("私钥"+ priKey);
+        String pubKey = "1967638ca43d4577d8dba166bff4437fde944270101f398a95b846ec2f8177d09f8abc5d62b6cd2c7216274d7abe0c8e04b0bb691207a32dd2e12d6bd2798672";
+        System.out.println("公钥"+ pubKey);
+
+        //明文
+        String text = "123123";
+        System.out.println("测试明文文本" + text);
+//        //签名验签测试
+//        String sign = "";
+//        try {
+//            sign = sign(priKey, Hex.toHexString(text.getBytes()));
+//        } catch (CryptoException e) {
+//            e.printStackTrace();
+//        }
+//        System.out.println("生成签名" + sign);
+//        boolean verify = verify(pubKey, Hex.toHexString(text.getBytes()), sign);
+//        System.out.println("验签结果" + verify);
+
+//        //加解密测试
+//        String encryptData = encrypt(pubKey, text);
+//        System.out.println("加密结果" + encryptData);
+//        String decryptData = decrypt(priKey, encryptData);
+//        System.out.println("解密结果" + decryptData);
+
+
+         String privateKeyHex = "6155d63ee27cbeca07f3e40c4f8856f1be8119fcbda1aadc7e0e595e52bad7bd";
+         String x = "1967638ca43d4577d8dba166bff4437fde944270101f398a95b846ec2f8177d0";
+         String y = "9f8abc5d62b6cd2c7216274d7abe0c8e04b0bb691207a32dd2e12d6bd2798672";
+
+        SM2 sm2 = new SM2(privateKeyHex,
+                x,
+                y);
+
+        String sm2encoderparam= sm2.encryptBcd(text, KeyType.PublicKey);
+        System.out.println("hutool加密:"+sm2encoderparam);
+
+
+        System.out.println("最早hutool加密:"+SM2CryptUtils.encrypt(text,pubKey));
+    }
+
+
+    /**
+     * 签名
+     *
+     * @param withId
+     *            可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes()
+     * @param srcData
+     * @return
+     * @throws CryptoException
+     */
+    public static String sign(String privateKey, byte[] withId, byte[] srcData)
+            throws Exception {
+
+        BCECPrivateKey bcecPrivateKey = getBCECPrivateKeyByPrivateKeyHex(privateKey);
+
+        ECPrivateKeyParameters priKeyParameters = convertPrivateKey(bcecPrivateKey);
+
+        SM2Signer signer = new SM2Signer();
+        CipherParameters param = null;
+        ParametersWithRandom pwr = new ParametersWithRandom(priKeyParameters, new SecureRandom());
+        if (withId != null) {
+            param = new ParametersWithID(pwr, withId);
+        } else {
+            param = pwr;
+        }
+        signer.init(true, param);
+        signer.update(srcData, 0, srcData.length);
+        System.out.println(srcData.length);
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < signer.generateSignature().length; i++) {
+            sb.append(String.format("%02x", signer.generateSignature()[i]));
+        }
+        return sb.toString();
+
+    }
+    private static X9ECParameters x9ECParameters = GMNamedCurves.getByName("sm2p256v1");
+
+    private static ECParameterSpec ecDomainParameters = new ECParameterSpec(x9ECParameters.getCurve(), x9ECParameters.getG(), x9ECParameters.getN());
+    /**
+     * 密钥转换
+     *
+     * @return
+     */
+    public static ECPrivateKeyParameters convertPrivateKey(BCECPrivateKey ecPriKey) {
+        ECParameterSpec parameterSpec = ecPriKey.getParameters();
+        ECDomainParameters domainParameters = new ECDomainParameters(parameterSpec.getCurve(), parameterSpec.getG(),
+                parameterSpec.getN(), parameterSpec.getH());
+        return new ECPrivateKeyParameters(ecPriKey.getD(), domainParameters);
+    }
+    public static BCECPrivateKey getBCECPrivateKeyByPrivateKeyHex(String privateKeyHex) {
+        BigInteger d = new BigInteger(privateKeyHex, 16);
+        ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(d, ecDomainParameters);
+        return new BCECPrivateKey("EC", ecPrivateKeySpec, BouncyCastleProvider.CONFIGURATION);
+    }
+}

+ 2 - 2
ui/src/utils/smutil.js

@@ -37,7 +37,7 @@ export function doSign(msgString) {
   // 1 - C1C3C2;	0 - C1C2C3;	默认为1
   let cipherMode = 1
   // 签名
-  let sign = sm2.doSignature(msgString, privateKey1, {hash: true, der: true})
+  let sign = sm2.doSignature(msgString, privateKey1, {hash: true, der: false})
   return sign;
 }
 
@@ -47,7 +47,7 @@ export function doVerifySignature(msgString, sigValueHex) {
   // 1 - C1C3C2;	0 - C1C2C3;	默认为1
   let cipherMode = 1
   // 签名
-  let verifyResult = sm2.doVerifySignature(msgString, sigValueHex, publicKey2, {hash: true, der: true}) // 验签结果
+  let verifyResult = sm2.doVerifySignature(msgString, sigValueHex, publicKey2, {hash: true, der: false}) // 验签结果
   return verifyResult;
 }