|
@@ -0,0 +1,139 @@
|
|
|
+package com.hjy.common.utils;
|
|
|
+
|
|
|
+import java.math.BigInteger;
|
|
|
+import java.security.NoSuchAlgorithmException;
|
|
|
+import java.security.SecureRandom;
|
|
|
+import java.util.Base64;
|
|
|
+
|
|
|
+import com.hjy.common.core.sm2.Sm2;
|
|
|
+import org.bouncycastle.asn1.gm.GMNamedCurves;
|
|
|
+import org.bouncycastle.asn1.x9.X9ECParameters;
|
|
|
+import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
|
|
|
+import org.bouncycastle.crypto.InvalidCipherTextException;
|
|
|
+import org.bouncycastle.crypto.engines.SM2Engine;
|
|
|
+import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
|
|
|
+import org.bouncycastle.crypto.params.ECDomainParameters;
|
|
|
+import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
|
|
|
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
|
|
+import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
|
|
+import org.bouncycastle.math.ec.ECPoint;
|
|
|
+import org.bouncycastle.util.encoders.Hex;
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @类名称 Sm2Utils.java
|
|
|
+ * @类描述 <pre>国密sm2工具类-适用于 js+java后端交互使用</pre>
|
|
|
+ * @作者 yw xingsfdz@163.com
|
|
|
+ * @创建时间 2021年4月13日 下午1:52:56
|
|
|
+ * @版本 5.0.0
|
|
|
+ *
|
|
|
+ * @修改记录
|
|
|
+ * <pre>
|
|
|
+ * 版本 修改人 修改日期 修改内容描述
|
|
|
+ * ----------------------------------------------
|
|
|
+ * 5.0.0 yw 2021年4月13日
|
|
|
+ * ----------------------------------------------
|
|
|
+ * </pre>
|
|
|
+ */
|
|
|
+public class Sm2Utils {
|
|
|
+
|
|
|
+ //流程 通过后台代码生产公私钥对,公钥提供给js端用于数据加密,私钥用于js端传来的密文串解密
|
|
|
+ private static ECDomainParameters domainParameters = null;
|
|
|
+ private static final String privateKey = "80cfeb110007a9a11295b9289c4b889063f35fe66e54d53fdbb5b8aa335d665a";//生成的私钥 用来解密
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取椭圆曲线
|
|
|
+ */
|
|
|
+ static {
|
|
|
+ //生成密钥对
|
|
|
+ X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
|
|
|
+ domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String args[]) {
|
|
|
+ String text = "04be17bf6fe47da1f34a01ad0ff67901241b72d103e998f2f7cc78a004703bdfb8d2c6e3939f4f708f3a57d872d58ec5c41bbe5976666bcb01acea43f5a1c68a62cc117c24821d17c3023035641894d7c978a5521f8dc6798515550c73071f9703602e0ee490157729b648c1cc3eb929c1a0501e12a216d42461117402";
|
|
|
+ verification(text);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @方法名称 genPUPRkey
|
|
|
+ * @功能描述 <pre>生成公私钥对 公钥给别人拿去加密传输数据,私钥留个自己用来解密</pre>
|
|
|
+ * @作者 yw
|
|
|
+ * @创建时间 2021年4月13日 下午1:57:07
|
|
|
+ * @throws NoSuchAlgorithmException
|
|
|
+ */
|
|
|
+ public static Sm2 genPUPRkey() throws NoSuchAlgorithmException {
|
|
|
+ //生成密钥对
|
|
|
+ ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
|
|
|
+ keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
|
|
|
+ AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
|
|
|
+
|
|
|
+ //私钥,16进制格式,自己保存,格式如80cfeb110007a9a11295b9289c4b889063f35fe66e54d53fdbb5b8aa335d665a
|
|
|
+ BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
|
|
|
+ String privateKeyHex = privatekey.toString(16);
|
|
|
+ System.out.println("私钥:" + privateKeyHex);
|
|
|
+
|
|
|
+ //公钥,16进制格式,发给前端,格式如0467e8c00b1fc2049aa006e75a7216eaf1fb42347b664ea63897917f1281427fa22254d39a3f5fd38e6773edc5eddc074dae27bfbe82d13094bfcbe6b344e89ee9
|
|
|
+ ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
|
|
|
+ String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
|
|
|
+ System.out.println("公钥:" + publicKeyHex);
|
|
|
+
|
|
|
+ Sm2 sm2 = new Sm2();
|
|
|
+ sm2.setPrivateKeyHex(privateKeyHex);
|
|
|
+ sm2.setPublicKeyHex(publicKeyHex);
|
|
|
+ return sm2;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解密
|
|
|
+ * @方法名称 decrypt
|
|
|
+ * @功能描述 <pre></pre>
|
|
|
+ * @作者 yw
|
|
|
+ * @创建时间 2021年4月13日 下午2:09:59
|
|
|
+ * @param ciphertext
|
|
|
+ * @param privatekey
|
|
|
+ * @throws InvalidCipherTextException
|
|
|
+ */
|
|
|
+ public static String decrypt(String ciphertext, String privatekey) throws InvalidCipherTextException {
|
|
|
+ String cipherData = ciphertext;//JS加密产生的密文
|
|
|
+ byte[] cipherDataByte = Hex.decode(cipherData);//格式转换
|
|
|
+
|
|
|
+ BigInteger privateKeyD = new BigInteger(privatekey, 16);//私钥Hex,还原私钥
|
|
|
+ ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
|
|
|
+
|
|
|
+ //用私钥解密
|
|
|
+ SM2Engine sm2Engine = new SM2Engine();
|
|
|
+ sm2Engine.init(false, privateKeyParameters);
|
|
|
+
|
|
|
+ //processBlock得到Base64格式,记得解码
|
|
|
+ byte[] arrayOfBytes = Base64.getDecoder().decode(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));
|
|
|
+
|
|
|
+ //得到明文:SM2 Encryption Test
|
|
|
+ String mtext = new String(arrayOfBytes);
|
|
|
+ System.out.println(mtext);
|
|
|
+ return mtext;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @方法名称 verification
|
|
|
+ * @功能描述 <pre>js的密文校验</pre>
|
|
|
+ * @作者 yw
|
|
|
+ * @创建时间 2021年4月13日 下午2:13:07
|
|
|
+ * @param ciphertext
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String verification(String ciphertext) {
|
|
|
+ String mtext = "";//明文
|
|
|
+ try {
|
|
|
+ mtext = decrypt(ciphertext, privateKey);
|
|
|
+ System.out.println("mtext:" + mtext);
|
|
|
+ } catch (InvalidCipherTextException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return mtext ;
|
|
|
+ }
|
|
|
+}
|