From fa7479cd93d2b87c3a62a7c954c1833df34f3f0c Mon Sep 17 00:00:00 2001
From: rain <167982779@qq.com>
Date: Sat, 03 Aug 2024 17:50:00 +0800
Subject: [PATCH] 国土调查注册对接,完成注册接口,完成SM2和SM4加密解密方法

---
 src/main/java/com/dji/sample/droneairport/utils/SM2/ModeTypeConstant.java     |   20 ++
 src/main/java/com/dji/sample/droneairport/utils/SM4Util.java                  |   57 ++++++
 src/main/java/com/dji/sample/droneairport/utils/SM2/Test.java                 |   19 ++
 src/main/java/com/dji/sample/droneairport/utils/SM2/KeyConstant.java          |   11 +
 src/main/java/com/dji/sample/droneairport/controller/RegistController.java    |   33 +++
 src/main/java/com/dji/sample/droneairport/utils/SM2/ModeTypeEnum.java         |   26 ++
 src/main/java/com/dji/sample/droneairport/model/dto/DroneStateDto.java        |   25 ++
 src/main/java/com/dji/sample/droneairport/model/param/RegistParam.java        |   16 +
 pom.xml                                                                       |   20 ++
 src/main/java/com/dji/sample/droneairport/service/RegistService.java          |   14 +
 src/main/java/com/dji/sample/droneairport/service/impl/RegistServiceImpl.java |   97 ++++++++++
 src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java         |    2 
 src/main/java/com/dji/sample/droneairport/utils/SM2/SecretCommon.java         |  118 +++++++++++++
 src/main/java/com/dji/sample/droneairport/model/param/AddDeviceParam.java     |   23 ++
 src/main/java/com/dji/sample/droneairport/utils/SM2/Utils.java                |   56 ++++++
 15 files changed, 534 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index f11da81..d349227 100644
--- a/pom.xml
+++ b/pom.xml
@@ -223,11 +223,14 @@
             <version>28.0</version>
         </dependency>
 
+
         <dependency>
             <groupId>cn.hutool</groupId>
-            <artifactId>hutool-core</artifactId>
-            <version>5.6.5</version>
+            <artifactId>hutool-all</artifactId>
+            <version>5.4.0</version>
+            <scope>compile</scope>
         </dependency>
+
 
         <dependency>
             <groupId>org.geotools</groupId>
@@ -312,6 +315,19 @@
             <artifactId>poi-ooxml</artifactId>
             <version>5.2.3</version>
         </dependency>
+
+        <!--SM4加密-->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15to18</artifactId>
+            <version>1.66</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk18on</artifactId>
+            <version>1.78.1</version>
+        </dependency>
     </dependencies>
 
 
diff --git a/src/main/java/com/dji/sample/droneairport/controller/RegistController.java b/src/main/java/com/dji/sample/droneairport/controller/RegistController.java
new file mode 100644
index 0000000..80401bb
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/controller/RegistController.java
@@ -0,0 +1,33 @@
+package com.dji.sample.droneairport.controller;
+
+import com.dji.sample.common.model.ResponseResult;
+import com.dji.sample.droneairport.model.param.AddDeviceParam;
+import com.dji.sample.droneairport.model.param.RegistParam;
+import com.dji.sample.droneairport.service.RegistService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RequestMapping("/droneAirport")
+@RestController
+public class RegistController {
+    @Autowired
+    private RegistService registService;
+
+    @PostMapping("/RegistService")
+    public ResponseResult resgitePort(@RequestBody RegistParam param) {
+        return ResponseResult.success(registService.registPort(param));
+    }
+
+    @PostMapping("/addDevice")
+    public ResponseResult registeDrone(@RequestBody AddDeviceParam param) {
+        return ResponseResult.success(registService.addDrone(param));
+    }
+    @PostMapping("/test")
+    public ResponseResult test(@RequestBody AddDeviceParam param) {
+        return ResponseResult.success(param);
+    }
+    @GetMapping("/getDroneStatus")
+    public ResponseResult droneStatus(@RequestParam String deviceid){
+        return ResponseResult.success(registService.getDroneState(deviceid));
+    }
+}
diff --git a/src/main/java/com/dji/sample/droneairport/model/dto/DroneStateDto.java b/src/main/java/com/dji/sample/droneairport/model/dto/DroneStateDto.java
new file mode 100644
index 0000000..72d5207
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/model/dto/DroneStateDto.java
@@ -0,0 +1,25 @@
+package com.dji.sample.droneairport.model.dto;
+
+import lombok.Data;
+
+@Data
+public class DroneStateDto {
+
+    private int mode_code;
+
+    private double longitude;
+
+    private double latitude;
+
+    private double height;
+
+    private double elevation;
+
+    private double gimbalPitch;
+
+    private double gimbalYal;
+
+    private int batteryCapacityPercent;
+
+    private int gpsState;
+}
diff --git a/src/main/java/com/dji/sample/droneairport/model/param/AddDeviceParam.java b/src/main/java/com/dji/sample/droneairport/model/param/AddDeviceParam.java
new file mode 100644
index 0000000..70c7435
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/model/param/AddDeviceParam.java
@@ -0,0 +1,23 @@
+package com.dji.sample.droneairport.model.param;
+
+import lombok.Data;
+
+@Data
+public class AddDeviceParam {
+
+    private String regioncode;
+
+    private String deviceid;
+
+    private String brand;
+
+    private String model;
+
+    private double longitude;
+
+    private double latitude;
+
+    private double height;
+
+    private double radius;
+}
diff --git a/src/main/java/com/dji/sample/droneairport/model/param/RegistParam.java b/src/main/java/com/dji/sample/droneairport/model/param/RegistParam.java
new file mode 100644
index 0000000..0eddcb7
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/model/param/RegistParam.java
@@ -0,0 +1,16 @@
+package com.dji.sample.droneairport.model.param;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+public class RegistParam {
+    @JsonProperty("serviceUrl")
+    private String serviceUrl;
+    @JsonProperty("liveStreamPluginUrl")
+    private String liveStreamPluginUrl;
+
+    private String contacts;
+
+    private String phone;
+}
diff --git a/src/main/java/com/dji/sample/droneairport/service/RegistService.java b/src/main/java/com/dji/sample/droneairport/service/RegistService.java
new file mode 100644
index 0000000..0414c0b
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/service/RegistService.java
@@ -0,0 +1,14 @@
+package com.dji.sample.droneairport.service;
+
+import com.dji.sample.droneairport.model.dto.DroneStateDto;
+import com.dji.sample.droneairport.model.param.AddDeviceParam;
+import com.dji.sample.droneairport.model.param.RegistParam;
+
+public interface RegistService {
+
+    String registPort(RegistParam param);
+
+    String addDrone(AddDeviceParam param);
+
+    DroneStateDto getDroneState(String deviceId);
+}
diff --git a/src/main/java/com/dji/sample/droneairport/service/impl/RegistServiceImpl.java b/src/main/java/com/dji/sample/droneairport/service/impl/RegistServiceImpl.java
new file mode 100644
index 0000000..62b4dea
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/service/impl/RegistServiceImpl.java
@@ -0,0 +1,97 @@
+package com.dji.sample.droneairport.service.impl;
+
+import com.dji.sample.droneairport.model.dto.DroneStateDto;
+import com.dji.sample.droneairport.model.param.AddDeviceParam;
+import com.dji.sample.droneairport.model.param.RegistParam;
+import com.dji.sample.droneairport.service.RegistService;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.List;
+
+@Service
+public class RegistServiceImpl implements RegistService {
+    private final RestTemplate restTemplate = new RestTemplate();
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+    public String registPort(RegistParam param) {
+        try {
+            // 构建请求体
+            String jsonBody = buildRequestBody(param);
+            // 设置请求头
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            headers.setAccept(List.of(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.ALL));
+            headers.set("Accept-Language", "zh-CN,zh;q=0.9");
+            headers.setConnection("keep-alive");
+            headers.set("x-auth-token", "");
+            headers.set("x-lc-token","");
+            // 构建请求实体
+            HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody, headers);
+            // 发送请求
+            ResponseEntity<String> response = restTemplate.exchange(
+                    "https://wrj.shuixiongit.com/drone-api/droneAirport/test",
+                    HttpMethod.POST,
+                    requestEntity,
+                    String.class);
+            return response.getBody();
+
+        } catch (Exception e) {
+            // 异常处理
+            throw new IllegalArgumentException("Request failed: " + e.getMessage(), e);
+        }
+    }
+
+    private String buildRequestBody(RegistParam param) {
+        try {
+            return objectMapper.writeValueAsString(param);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException("数据有误", e);
+        }
+    }
+
+    @Override
+    public String addDrone(AddDeviceParam param) {
+        try {
+            // 构建请求体
+            String jsonBody = buildRequestBody(param);
+            // 设置请求头
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            headers.setAccept(List.of(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.ALL));
+            headers.set("Accept-Language", "zh-CN,zh;q=0.9");
+            headers.setConnection("keep-alive");
+            headers.set("x-auth-token", "");
+            headers.set("x-lc-token","");
+            // 构建请求实体
+            HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody, headers);
+            // 发送请求
+            ResponseEntity<String> response = restTemplate.exchange(
+                    "https://wrj.shuixiongit.com/drone-api/droneAirport/test",
+                    HttpMethod.POST,
+                    requestEntity,
+                    String.class);
+            return response.getBody();
+
+        } catch (Exception e) {
+            // 异常处理
+            throw new IllegalArgumentException("Request failed: " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public DroneStateDto getDroneState(String deviceId) {
+        return null;
+    }
+
+    private String buildRequestBody(AddDeviceParam param) {
+        try {
+            return objectMapper.writeValueAsString(param);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException("数据有误", e);
+        }
+    }
+}
diff --git a/src/main/java/com/dji/sample/droneairport/utils/SM2/KeyConstant.java b/src/main/java/com/dji/sample/droneairport/utils/SM2/KeyConstant.java
new file mode 100644
index 0000000..bf71d51
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/utils/SM2/KeyConstant.java
@@ -0,0 +1,11 @@
+package com.dji.sample.droneairport.utils.SM2;
+
+public class KeyConstant {
+
+    public static final String PRIVATE_KEY = "pveky"; // 私钥
+    public static final String PUBLIC_KEY = "pbcky"; // 公钥
+
+    public static final String GM_NAME_CURVE = "sm2p256v1";
+    public static final String ALGORITHM = "SHA1PRNG";
+
+}
diff --git a/src/main/java/com/dji/sample/droneairport/utils/SM2/ModeTypeConstant.java b/src/main/java/com/dji/sample/droneairport/utils/SM2/ModeTypeConstant.java
new file mode 100644
index 0000000..65fc9f3
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/utils/SM2/ModeTypeConstant.java
@@ -0,0 +1,20 @@
+package com.dji.sample.droneairport.utils.SM2;
+
+import org.bouncycastle.crypto.engines.SM2Engine;
+
+public class ModeTypeConstant {
+
+    public static final String BASE = "base";
+    public static final String BC = "bc";
+
+    @Deprecated
+    public static final SM2Engine.Mode BASE_MODE = SM2Engine.Mode.C1C3C2;
+    @Deprecated
+    public static final SM2Engine.Mode BC_MODE = SM2Engine.Mode.C1C2C3;
+
+    public static ModeTypeEnum getMode(String modeType){
+        if (ModeTypeEnum.BASE_MODE.getType().equals(modeType)) return ModeTypeEnum.BASE_MODE;
+        return ModeTypeEnum.BC_MODE;
+    }
+
+}
diff --git a/src/main/java/com/dji/sample/droneairport/utils/SM2/ModeTypeEnum.java b/src/main/java/com/dji/sample/droneairport/utils/SM2/ModeTypeEnum.java
new file mode 100644
index 0000000..8b444a1
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/utils/SM2/ModeTypeEnum.java
@@ -0,0 +1,26 @@
+package com.dji.sample.droneairport.utils.SM2;
+
+import org.bouncycastle.crypto.engines.SM2Engine;
+
+public enum ModeTypeEnum {
+
+    BASE_MODE(ModeTypeConstant.BASE, SM2Engine.Mode.C1C3C2),
+    BC_MODE(ModeTypeConstant.BC, SM2Engine.Mode.C1C2C3);
+
+    private String type;
+    private SM2Engine.Mode mode;
+
+    ModeTypeEnum(String type, SM2Engine.Mode mode) {
+        this.type = type;
+        this.mode = mode;
+    }
+
+    public String getType(){
+        return type;
+    }
+
+    public SM2Engine.Mode getMode(){
+        return mode;
+    }
+
+}
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");
+    }
+
+}
diff --git a/src/main/java/com/dji/sample/droneairport/utils/SM2/Test.java b/src/main/java/com/dji/sample/droneairport/utils/SM2/Test.java
new file mode 100644
index 0000000..66ee84c
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/utils/SM2/Test.java
@@ -0,0 +1,19 @@
+package com.dji.sample.droneairport.utils.SM2;
+
+import java.util.Map;
+
+public class Test {
+
+    public static void main(String[] args) throws Exception {
+        Map<String, String> createKeyPair = Utils.createKeyPair();
+        System.out.println("秘钥对:" + createKeyPair);
+        String privateKey = createKeyPair.get(KeyConstant.PRIVATE_KEY);
+        String publicKey = createKeyPair.get(KeyConstant.PUBLIC_KEY);
+        String text = "I believe you can do anything";
+        String encrypt = Utils.encrypt(text, "049709f467dfdc4382657e081d18d4cf781f06996b2df6876f061615ff4a3ead7daba0fbc2b98c1a4ddee53db93f62b0f530b403e34141eb775277f434406a679a",ModeTypeEnum.BASE_MODE.getType());
+        System.out.println("加密后密文:" + encrypt);
+        String decrypt = Utils.decrypt(encrypt, "8b5afb843ca2a2d5bb12fc3442e7a17857a1d41c67c8212bb98a4943e28dfe8b",ModeTypeEnum.BASE_MODE.getType());
+        System.out.println("解密后明文:" + decrypt);
+    }
+
+}
diff --git a/src/main/java/com/dji/sample/droneairport/utils/SM2/Utils.java b/src/main/java/com/dji/sample/droneairport/utils/SM2/Utils.java
new file mode 100644
index 0000000..3cf6efe
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/utils/SM2/Utils.java
@@ -0,0 +1,56 @@
+package com.dji.sample.droneairport.utils.SM2;
+
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+
+public class Utils {
+
+    /**
+     * get key pair
+     */
+    public static Map<String, String> createKeyPair() throws NoSuchAlgorithmException {
+        return SecretCommon.createKeyPair();
+    }
+
+    /**
+     * encrypt
+     * @param plainText 需加密的明文字符串
+     * @param publicKey 公钥
+     */
+    public static String encrypt(String plainText, String publicKey) throws IOException, InvalidCipherTextException {
+        return encrypt(plainText, publicKey, ModeTypeConstant.BASE);
+    }
+
+    /**
+     * encrypt
+     * @param plainText 需加密的明文字符串
+     * @param publicKey 公钥
+     * @param modeType base:标准;bc:BC模式
+     */
+    public static String encrypt(String plainText, String publicKey, String modeType) throws IOException, InvalidCipherTextException {
+        return SecretCommon.encrypt(plainText, publicKey, ModeTypeConstant.getMode(modeType));
+    }
+
+    /**
+     * decrypt
+     * @param cipherText 需加密的字符串
+     * @param privateKey 私钥
+     */
+    public static String decrypt(String cipherText, String privateKey) throws InvalidCipherTextException, UnsupportedEncodingException {
+        return decrypt(cipherText, privateKey, ModeTypeConstant.BASE);
+    }
+
+    /**
+     * decrypt
+     * @param cipherText 需加密的字符串
+     * @param privateKey 私钥
+     * @param modeType base:标准;bc:BC模式
+     */
+    public static String decrypt(String cipherText, String privateKey, String modeType) throws InvalidCipherTextException, UnsupportedEncodingException {
+        return SecretCommon.decrypt(cipherText, privateKey, ModeTypeConstant.getMode(modeType));
+    }
+
+}
diff --git a/src/main/java/com/dji/sample/droneairport/utils/SM4Util.java b/src/main/java/com/dji/sample/droneairport/utils/SM4Util.java
new file mode 100644
index 0000000..2312585
--- /dev/null
+++ b/src/main/java/com/dji/sample/droneairport/utils/SM4Util.java
@@ -0,0 +1,57 @@
+package com.dji.sample.droneairport.utils;
+
+import org.bouncycastle.crypto.engines.SM4Engine;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.bouncycastle.crypto.paddings.PKCS7Padding;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Base64;
+
+public class SM4Util {
+    public static String encrypt(byte[] key, byte[] input) {
+        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new SM4Engine(), new PKCS7Padding());
+        cipher.init(true, new KeyParameter(key));  // ECB模式下不需要IV
+        byte[] output = new byte[cipher.getOutputSize(input.length)];
+        int length = cipher.processBytes(input, 0, input.length, output, 0);
+        try {
+            length += cipher.doFinal(output, length);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        String encoded = Base64.getEncoder().encodeToString(Arrays.copyOf(output, length));
+        return encoded;
+    }
+
+    public static byte[] decrypt(byte[] key, byte[] input) {
+        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new SM4Engine(), new PKCS7Padding());
+        cipher.init(false, new KeyParameter(key));  // ECB模式下不需要IV
+        byte[] output = new byte[cipher.getOutputSize(input.length)];
+        int length = cipher.processBytes(input, 0, input.length, output, 0);
+        try {
+            length += cipher.doFinal(output, length);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Arrays.copyOf(output, length);
+    }
+
+    public static void main(String[] args) {
+        byte[] key = "jsimjrby3wqb7dbq".getBytes(StandardCharsets.UTF_8); // 16字节密钥
+
+        // 原始明文
+        String plaintext = "hello";
+
+        System.out.println("Encoded: " + encrypt(key, plaintext.getBytes(StandardCharsets.UTF_8)));
+
+        // 解码并解密
+        byte[] decoded = Base64.getDecoder().decode(encrypt(key, plaintext.getBytes(StandardCharsets.UTF_8)));
+        byte[] decrypted = decrypt(key, decoded);
+
+        // 输出结果
+        System.out.println("Plaintext: " + plaintext);
+        System.out.println("Encrypted (Base64): " + encrypt(key, plaintext.getBytes(StandardCharsets.UTF_8)));
+        System.out.println("Decrypted: " + new String(decrypted, StandardCharsets.UTF_8));
+    }
+}
diff --git a/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java b/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java
index e5a09dd..648305a 100644
--- a/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java
+++ b/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java
@@ -227,7 +227,7 @@
         String objectKey = callback.getFile().getObjectKey();
         callback.getFile().setPath(objectKey.substring(objectKey.indexOf("/") + 1, objectKey.lastIndexOf("/")));
         int count =fileService.saveFile(job.getWorkspaceId(), callback.getFile());
-        fileService.saveFiles(job.getWorkspaceId(), callback.getFile());
+//        fileService.saveFiles(job.getWorkspaceId(), callback.getFile());
 //        fileService.saveZipFile(job.getWorkspaceId(),callback.getFile());
         return count > 0;
     }

--
Gitblit v1.9.3