|
|
@@ -0,0 +1,139 @@
|
|
|
+package com.emoon.openplatform.controller;
|
|
|
+
|
|
|
+import cn.hutool.http.HttpStatus;
|
|
|
+import com.emoon.openplatform.util.HttpUtil;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.common.core.domain.R;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
+
|
|
|
+import javax.crypto.Cipher;
|
|
|
+import javax.crypto.spec.IvParameterSpec;
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.Base64;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author destiny
|
|
|
+ * @description:
|
|
|
+ * @date 2025/9/23 17:44
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RestController
|
|
|
+@RequestMapping("/Send")
|
|
|
+@CrossOrigin(origins = "*")
|
|
|
+public class TokenController {
|
|
|
+
|
|
|
+ public static final String NETWORK = "1";
|
|
|
+ public static final String NETWORK_LOCAL = "2";
|
|
|
+ @Value("${sm4.key}")
|
|
|
+ private String sm4Key;
|
|
|
+
|
|
|
+ @Value("${sm4.private-key}")
|
|
|
+ private String sm4PrivateKey;
|
|
|
+
|
|
|
+ @Value("${sm4.public-key}")
|
|
|
+ private String sm4PublicKey;
|
|
|
+
|
|
|
+ @Value("${sm4.open-url}")
|
|
|
+ private String sm4OpenUrl;
|
|
|
+
|
|
|
+ @Value("${sm4.open-url-local}")
|
|
|
+ private String sm4OpenUrlLocal;
|
|
|
+
|
|
|
+ @PostMapping("/dataSM4")
|
|
|
+ public R<String> getToken(@RequestParam(required = false, defaultValue = "") String token,
|
|
|
+ @RequestParam String model,
|
|
|
+ @RequestParam String network,
|
|
|
+ @RequestParam("data") String dataJson) {
|
|
|
+ try {
|
|
|
+ String result = dataSM4(token, model, network, dataJson);
|
|
|
+ return R.ok(result);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Failed to get token: {}", e.getMessage(), e);
|
|
|
+ return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, "获取令牌失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public String dataSM4(String token, String model, String network, String dataJson) throws Exception {
|
|
|
+ // 判断该请求是否需要生成token
|
|
|
+ if ("noUse".equals(token)) {
|
|
|
+ return "noToken";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 组装请求的数据为base64格式
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ Map<String, Object> data = new HashMap<>();
|
|
|
+ data.put("model", model);
|
|
|
+ data.put("network", network);
|
|
|
+
|
|
|
+ // 解析输入数据
|
|
|
+ Object inputData = objectMapper.readValue(dataJson, Object.class);
|
|
|
+ data.put("input", inputData);
|
|
|
+
|
|
|
+ String jsonData = objectMapper.writeValueAsString(data);
|
|
|
+ System.out.println("参数标记: " + jsonData);
|
|
|
+
|
|
|
+ // Base64编码
|
|
|
+ String base64Data = Base64.getEncoder().encodeToString(jsonData.getBytes(StandardCharsets.UTF_8));
|
|
|
+
|
|
|
+ // 对请求的参数进行SM4加密
|
|
|
+
|
|
|
+ byte[] encryptedBinary = sm4Encrypt(base64Data, sm4PrivateKey, sm4Key);
|
|
|
+ String encryptedBase64 = Base64.getEncoder().encodeToString(encryptedBinary);
|
|
|
+
|
|
|
+ // 创建最终的含有SM4的IV的数据
|
|
|
+ Map<String, String> modifiedDataMap = new HashMap<>();
|
|
|
+ modifiedDataMap.put("encryptedBase64", encryptedBase64);
|
|
|
+ modifiedDataMap.put("smIV", sm4Key);
|
|
|
+ modifiedDataMap.put("publicKey", sm4PublicKey);
|
|
|
+
|
|
|
+ String modifiedDataJson = objectMapper.writeValueAsString(modifiedDataMap);
|
|
|
+ String modifiedDataBase64 = Base64.getEncoder().encodeToString(modifiedDataJson.getBytes(StandardCharsets.UTF_8));
|
|
|
+
|
|
|
+ // 将 '+' 替换为 '-','/' 替换为 '_'
|
|
|
+ String modifiedData = modifiedDataBase64.replace('+', '-').replace('/', '_');
|
|
|
+
|
|
|
+ // 将加密的参数发送给开放平台,获取短令牌
|
|
|
+ String url;
|
|
|
+ if (StringUtils.equals(NETWORK, network)) {
|
|
|
+ url = sm4OpenUrl + "/Apis/getToken";
|
|
|
+ } else if (StringUtils.equals(NETWORK_LOCAL, network)) {
|
|
|
+ url = sm4OpenUrlLocal + "/Apis/getToken";
|
|
|
+ } else {
|
|
|
+ throw new IllegalArgumentException("Invalid network parameter");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ Map<String, String> encryption = new HashMap<>();
|
|
|
+ encryption.put("information", modifiedData);
|
|
|
+
|
|
|
+ String response = HttpUtil.curlPost(url, encryption);
|
|
|
+ // 解析响应获取token(这里简化处理,实际应使用JSON解析库)
|
|
|
+ // 假设响应格式为 {"token":"xxx","code":0}
|
|
|
+
|
|
|
+ return parseTokenFromResponse(response);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 简化的响应解析方法
|
|
|
+ private String parseTokenFromResponse(String response) {
|
|
|
+ // 实际应该使用JSON解析库如Jackson或Gson
|
|
|
+ // 这里简化处理,假设响应格式为 {"token":"xxx","code":0}
|
|
|
+ int start = response.indexOf("\"token\":\"") + 9;
|
|
|
+ int end = response.indexOf("\"", start);
|
|
|
+ return response.substring(start, end);
|
|
|
+ }
|
|
|
+
|
|
|
+ // SM4加密方法(使用AES算法模拟SM4)
|
|
|
+ private byte[] sm4Encrypt(String data, String key, String iv) throws Exception {
|
|
|
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
|
|
+ SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
|
|
|
+ IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
|
|
|
+ return cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
|
|
+ }
|
|
|
+}
|