From b7c05407dcf01cd7c01fde0efdf2a6a0283d4016 Mon Sep 17 00:00:00 2001
From: rain <167982779@qq.com>
Date: Sat, 03 Aug 2024 17:50:22 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/ht-dev' into ht-dev

---
 src/main/java/com/dji/sample/droneairport/utils/SM2/SecretCommon.java |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 118 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/dji/sample/droneairport/utils/SM2/SecretCommon.java b/src/main/java/com/dji/sample/droneairport/utils/SM2/SecretCommon.java
new file mode 100644
index 0000000..60a172f
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/utils/SM2/SecretCommon.java
@@ -0,0 +1,118 @@
+package com.dji.sample.droneairport.utils.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.crypto.params.ParametersWithRandom;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
+import org.bouncycastle.util.encoders.Hex;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * SM2公钥密码算法(非对称算法)
+ * SM2椭圆曲线公钥密码算法是我国自主设计的公钥密码算法。
+ * 包括SM2-1椭圆曲线数字签名算法;SM2-2椭圆曲线密钥交换协议;SM2-3椭圆曲线公钥加密算法,分别用于实现数字签名密钥协商和数据加密等功能。
+ * SM2算法与RSA算法不同的是,SM2算法是基于椭圆曲线上点群离散对数难题,相对于RSA算法,256位的SM2密码强度已经比2048位的RSA密码强度要高。
+ */
+public class SecretCommon {
+
+    //获取椭圆曲线
+    public static synchronized ECDomainParameters getECDomainParameters() {
+        X9ECParameters sm2ECParameters = GMNamedCurves.getByName(KeyConstant.GM_NAME_CURVE);
+        return new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
+    }
+
+    /**
+     * get key pair
+     */
+    public static Map<String, String> createKeyPair() throws NoSuchAlgorithmException {
+        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
+        keyPairGenerator.init(new ECKeyGenerationParameters(getECDomainParameters(), SecureRandom.getInstance(KeyConstant.ALGORITHM)));
+        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
+        Map<String, String> map = new HashMap<>();
+        BigInteger bigInteger = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
+        map.put(KeyConstant.PRIVATE_KEY, ByteUtils.toHexString(bigInteger.toByteArray()));
+        // 把公钥放入map中,默认压缩公钥
+        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥,04的时候,可以去掉前面的04
+        ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
+        map.put(KeyConstant.PUBLIC_KEY, ByteUtils.toHexString(ecPoint.getEncoded(false)));
+        return map;
+    }
+
+    /**
+     * 加密
+     * @param plainText 需加密的明文字符串
+     * @param publicKey 公钥
+     * @param modeType base:标准;bc:BC模式
+     */
+    public static String encrypt(String plainText, String publicKey, ModeTypeEnum modeType) throws IOException, InvalidCipherTextException {
+        return encrypt(plainText.getBytes(), publicKey, modeType.getMode());
+    }
+
+    /**
+     * 加密
+     * @param plainByte 需加密的明文字节数组
+     * @param publicKey 公钥
+     * @param mode 加密模式 ModeTypeEnum
+     */
+    public static String encrypt(byte[] plainByte, String publicKey, SM2Engine.Mode mode) throws IOException, InvalidCipherTextException {
+        ECDomainParameters domainParameters = getECDomainParameters();
+        //提取公钥点
+        ECPoint ecPoint = domainParameters.getCurve().decodePoint(ByteUtils.fromHexString(publicKey));
+        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
+        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(ecPoint, domainParameters);
+        SM2Engine sm2Engine = new SM2Engine(mode);
+        sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));
+        return ByteUtils.toHexString(sm2Engine.processBlock(plainByte, 0, plainByte.length));
+    }
+
+    /**
+     * 解密
+     * @param cipherText 需加密的字符串
+     * @param privateKey 私钥
+     * @param modeType base:标准;bc:BC模式
+     */
+    public static String decrypt(String cipherText, String privateKey, ModeTypeEnum modeType) throws InvalidCipherTextException, UnsupportedEncodingException {
+        return decrypt(Hex.decode(cipherText), privateKey, modeType.getMode());
+    }
+
+    /**
+     * 解密
+     * @param cipherDataByte 密文字节数组
+     * @param privateKeyHex 私钥
+     * @param mode 解密模式 ModeTypeEnum
+     */
+    public static String decrypt(byte[] cipherDataByte, String privateKeyHex, SM2Engine.Mode mode) throws InvalidCipherTextException, UnsupportedEncodingException {
+        // 将 HEX 私钥转换为 BigInteger
+        BigInteger bigInteger = new BigInteger(privateKeyHex, 16);
+
+        // 创建 EC 私钥参数
+        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(bigInteger, getECDomainParameters());
+
+        // 初始化 SM2 引擎
+        SM2Engine sm2Engine = new SM2Engine(mode);
+        sm2Engine.init(false, privateKeyParameters);
+
+        // 解密
+        byte[] decryptedBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
+
+        // 将解密后的字节数组转换为 UTF-8 字符串
+        return new String(decryptedBytes, "UTF-8");
+    }
+
+}

--
Gitblit v1.9.3