Browse Source

互联互通对接调试:支持双向加密配置

skyline 1 year ago
parent
commit
d8df0b5d33

+ 5 - 4
common/src/main/java/com/kym/common/utils/PlatformAesUtil.java

@@ -75,11 +75,12 @@ public class PlatformAesUtil {
     /**
      * AES 解密操作
      *
-     * @param config  互联互通平台配置
+     * @param dataSecret
+     * @param dataSecretIv
      * @param content
      * @return
      */
-    public static String decrypt(Platform config, String content) {
+    public static String decrypt(String dataSecret, String dataSecretIv, String content) {
         if (content == null || content.isEmpty()) {
             return content;
         }
@@ -87,9 +88,9 @@ public class PlatformAesUtil {
         try {
             //实例化
             Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
-            IvParameterSpec zeroIv = new IvParameterSpec(config.getDataSecretIv().getBytes(StandardCharsets.UTF_8));
+            IvParameterSpec zeroIv = new IvParameterSpec(dataSecretIv.getBytes(StandardCharsets.UTF_8));
 
-            SecretKeySpec skeySpec = new SecretKeySpec(config.getDataSecret().getBytes(StandardCharsets.UTF_8), AES);
+            SecretKeySpec skeySpec = new SecretKeySpec(dataSecret.getBytes(StandardCharsets.UTF_8), AES);
             //SecretKeySpec skeySpec = getSecretKey(key);
             cipher.init(Cipher.DECRYPT_MODE, skeySpec, zeroIv);
 

+ 46 - 7
entity/src/main/java/com/kym/entity/admin/Platform.java

@@ -2,7 +2,6 @@ package com.kym.entity.admin;
 
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.kym.entity.BaseEntity;
-import java.io.Serializable;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -27,35 +26,70 @@ public class Platform extends BaseEntity {
     private Long companyId;
 
     /**
-     * 平台名称
+     * 公司名称(服务端)
+     */
+    private String companyName;
+
+    /**
+     * 平台名称(需求端)
      */
     private String platformName;
 
     /**
-     * 运营商ID
+     * 运营商ID(服务端)
      */
     private String operatorId;
 
     /**
-     * 运营商密钥
+     * 运营商密钥(服务端)
      */
     private String operatorSecret;
 
     /**
-     * 消息密钥
+     * 消息密钥(服务端)
      */
     private String dataSecret;
 
     /**
-     * 消息密钥初始化向量
+     * 消息密钥初始化向量(服务端)
      */
     private String dataSecretIv;
 
     /**
-     * 签名密钥
+     * 签名密钥(服务端)
      */
     private String sigSecret;
 
+    /**
+     * 平台名称(需求端)
+     */
+    private String userPlatformName;
+
+    /**
+     * 运营商ID(服务端)
+     */
+    private String userOperatorId;
+
+    /**
+     * 运营商密钥(需求端)
+     */
+    private String userOperatorSecret;
+
+    /**
+     * 消息密钥(需求端)
+     */
+    private String userDataSecret;
+
+    /**
+     * 消息密钥初始化向量(需求端)
+     */
+    private String userDataSecretIv;
+
+    /**
+     * 签名密钥(需求端)
+     */
+    private String userSigSecret;
+
     /**
      * 最小充电余额(分)
      */
@@ -66,6 +100,11 @@ public class Platform extends BaseEntity {
      */
     private String apiDomain;
 
+    /**
+     * 通知推送地址URL
+     */
+    private String notifyDomain;
+
     /**
      * 环境:dev开发,test测试,prod生产
      */

+ 2 - 2
miniapp/src/main/java/com/kym/miniapp/controller/ChargerController.java

@@ -201,8 +201,8 @@ public class ChargerController {
      */
     @ApiLog("互联互通平台推送请求Token")
     @PostMapping("/{platformName}/query_token")
-    PlatformResponse queryToken(@PathVariable(value = "platformName", required = false) String platformName) {
-        return new PlatformResponse(enNotifyService.queryToken(platformName));
+    PlatformResponse queryToken(@PathVariable(value = "platformName", required = false) String platformName, @RequestBody JSONObject json) {
+        return new PlatformResponse(enNotifyService.queryToken(platformName,json));
     }
 
     /**

+ 6 - 4
service/src/main/java/com/kym/service/admin/impl/StationServiceImpl.java

@@ -7,7 +7,6 @@ import com.baomidou.dynamic.datasource.annotation.DS;
 import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.kym.common.annotation.DynamicCache;
-import com.kym.service.platform.CommonApi;
 import com.kym.common.exception.BusinessException;
 import com.kym.common.utils.CommUtil;
 import com.kym.common.utils.PlatformAesUtil;
@@ -22,8 +21,9 @@ import com.kym.mapper.admin.StationMapper;
 import com.kym.service.admin.*;
 import com.kym.service.cache.KymCache;
 import com.kym.service.cache.PlatformCache;
-import com.kym.service.platform.PlatformApiService;
 import com.kym.service.mybatisplus.MyBaseServiceImpl;
+import com.kym.service.platform.CommonApi;
+import com.kym.service.platform.PlatformApiService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.aop.framework.AopContext;
 import org.springframework.beans.BeanUtils;
@@ -121,7 +121,8 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
      * @return
      */
     JSONObject parsePlatformResponseData(PlatformResponse response, String platformName) {
-        return JSONObject.parseObject(PlatformAesUtil.decrypt(PlatformCache.INSTANCE.getPlatformByName(platformName), response.getData()));
+        var platform = PlatformCache.INSTANCE.getPlatformByName(platformName);
+        return JSONObject.parseObject(PlatformAesUtil.decrypt(platform.getDataSecret(), platform.getDataSecretIv(), response.getData()));
     }
 
     /**
@@ -240,7 +241,8 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
                     }
                     """.formatted(String.join("\",\"", ids));
             var response = enPlusService.platformPost(platformName, CommonApi.EN_PLUS_QUERY_STATION_STATUS.getApi(platformName), enPlusService.buildPlatformParams(platformName, param));
-            var enStationStatus = JSONObject.parseObject(PlatformAesUtil.decrypt(PlatformCache.INSTANCE.getPlatformByName(platformName),response.getData()));
+            var platform = PlatformCache.INSTANCE.getPlatformByName(platformName);
+            var enStationStatus = JSONObject.parseObject(PlatformAesUtil.decrypt(platform.getDataSecret(), platform.getDataSecretIv(), response.getData()));
             res.addAll(enStationStatus.getJSONArray("StationStatusInfos").toJavaList(PlatformStationStatusInfo.class));
         });
         return res;

+ 1 - 1
service/src/main/java/com/kym/service/platform/PlatformNotifyService.java

@@ -19,5 +19,5 @@ public interface PlatformNotifyService {
     String handleNotificationChargeOrderInfo(String platformName, JSONObject json);
 
     String handleNotificationStationStatus(String platformName, JSONObject json);
-    String queryToken(String platformName);
+    String queryToken(String platformName, JSONObject json);
 }

+ 8 - 7
service/src/main/java/com/kym/service/platform/impl/PlatformApiServiceImpl.java

@@ -83,7 +83,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
         if (0 == response.getRet()) {
             return response;
         } else {
-            log.error(":url:{}\n params:{}\ntoken:{}\n返回信息:{}", url, params, token, response);
+            log.error(":url:{}, params:{},token:{},返回信息:{}", url, params, token, response);
             if (4002 == response.getRet()) {
                 // 如果返回Ret=4002,token错误的情况下,删除redis中的token,如果是预约订单则将此订单设置为延迟启动
                 redisTemplate.delete(RedisKeys.EN_PLUS_TOKEN + platformName);
@@ -101,7 +101,8 @@ public class PlatformApiServiceImpl implements PlatformApiService {
      * @return
      */
     JSONObject parsePlatformResponseData(PlatformResponse response, String platformName) {
-        return JSONObject.parseObject(PlatformAesUtil.decrypt(PlatformCache.INSTANCE.getPlatformByName(platformName), response.getData()));
+        var platform = PlatformCache.INSTANCE.getPlatformByName(platformName);
+        return JSONObject.parseObject(PlatformAesUtil.decrypt(platform.getDataSecret(), platform.getDataSecretIv(), response.getData()));
     }
 
 
@@ -125,7 +126,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "OperatorID":"%s",
                     "OperatorSecret":"%s"
                 }
-                """.formatted(PlatformCache.INSTANCE.getPlatformByName(platformName).getOperatorId(), PlatformCache.INSTANCE.getPlatformByName(platformName).getOperatorSecret());
+                """.formatted(PlatformCache.INSTANCE.getPlatformByName(platformName).getUserOperatorId(), PlatformCache.INSTANCE.getPlatformByName(platformName).getOperatorSecret());
 
         var requestParams = buildPlatformParams(platformName, data);
 
@@ -158,7 +159,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
         if (response != null && 0 == response.getRet()) {
             return response;
         } else {
-            log.error("互联互通接口数据异常:url:{}\n params:{}\n返回信息:{}", url, params, response);
+            log.error("互联互通接口数据异常:url:{}, params:{},返回信息:{}", url, params, response);
             throw new BusinessException(ResponseEnum.EN_PLUS_API_EXCEPTION);
         }
     }
@@ -181,7 +182,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
         // 自增序列
         var seq = timeStamp.substring(timeStamp.length() - 4);
         // 使用SigSecret以HMAC-MD5算法对消息体签名(签名顺序:OperatorId、Data、TimeStamp、Seq)
-        var signString = platform.getOperatorId() + dataStr + timeStamp + seq;
+        var signString = platform.getUserOperatorId() + dataStr + timeStamp + seq;
         HMac mac = new HMac(HmacAlgorithm.HmacMD5, platform.getSigSecret().getBytes());
         // 签名(转为大写)
         var sign = mac.digestHex(signString).toUpperCase();
@@ -213,12 +214,12 @@ public class PlatformApiServiceImpl implements PlatformApiService {
         var Seq = json.getString("Seq");
         var Sig = json.getString("Sig");
         var signString = OperatorID + Data + TimeStamp + Seq;
-        HMac mac = new HMac(HmacAlgorithm.HmacMD5, platform.getSigSecret().getBytes());
+        HMac mac = new HMac(HmacAlgorithm.HmacMD5, platform.getUserSigSecret().getBytes());
         // 签名(转为大写)
         var sign = mac.digestHex(signString).toUpperCase();
         if (sign.equals(Sig)) {
             // 解密数据
-            return PlatformAesUtil.decrypt(platform, Data);
+            return PlatformAesUtil.decrypt(platform.getUserDataSecret(), platform.getUserDataSecretIv(), Data);
         } else {
             // 验签失败
             PlatformResponse enResponse = new PlatformResponse();

+ 3 - 1
service/src/main/java/com/kym/service/platform/impl/PlatformNotifyServiceImpl.java

@@ -82,7 +82,9 @@ public class PlatformNotifyServiceImpl implements PlatformNotifyService {
     }
 
     @Override
-    public String queryToken(String platformName) {
+    public String queryToken(String platformName, JSONObject json) {
+        var data = enPlusService.signValidation(platformName, json);
+        LOGGER.info("【{}互联互通平台推送】收到请求快与慢Token:{},解密数据:{}", platformName, json, data);
         var platform = PlatformCache.INSTANCE.getPlatformByName(platformName);
         // 查询缓存,存在则返回值和过期时间,不存在则重新生成并缓存
         var token = redisTemplate.opsForValue().get(RedisKeys.PLATFORM_TOKEN + platformName);