Browse Source

互联互通对接调试:信息加解密

skyline 1 year ago
parent
commit
6d0f15bdc4

+ 0 - 45
common/src/main/java/com/kym/common/enums/EnPlusApi.java

@@ -1,45 +0,0 @@
-package com.kym.common.enums;
-
-import cn.hutool.extra.spring.SpringUtil;
-import com.kym.common.config.EnPlusConfig;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-
-/**
- * @author skyline
- * @description EN+接口
- * @date 2023-07-29 12:33
- */
-@AllArgsConstructor
-@Getter
-public enum EnPlusApi implements Api {
-
-    // 认证-获取token
-    EN_PLUS_QUERY_TOKEN(Constants.DOMAIN + "query_token", RequestMethod.POST), //获取AccessToken
-
-    // 站点
-    EN_PLUS_QUERY_STATION_INFO(Constants.DOMAIN + "query_stations_info", RequestMethod.POST), // 站点信息
-    EN_PLUS_QUERY_STATION_STATUS(Constants.DOMAIN + "query_station_status", RequestMethod.POST), // 站点状态
-    EN_PLUS_QUERY_STATION_STATS(Constants.DOMAIN + "query_station_stats", RequestMethod.POST), // 站点统计
-    //充电
-    EN_PLUS_QUERY_EQUIP_AUTH(Constants.DOMAIN + "query_equip_auth", RequestMethod.POST), // 请求设备认证
-    EN_PLUS_QUERY_EQUIP_BUSINESS_POLICY(Constants.DOMAIN + "query_equip_business_policy", RequestMethod.POST), // 查询业务策略信息
-    EN_PLUS_QUERY_START_CHARGE(Constants.DOMAIN + "query_start_charge", RequestMethod.POST), // 查询启动充电
-    EN_PLUS_QUERY_STOP_CHARGE(Constants.DOMAIN + "query_stop_charge", RequestMethod.POST), // 请求停止充电
-    EN_PLUS_QUERY_EQUIP_CHARGE_STATUS(Constants.DOMAIN + "query_equip_charge_status", RequestMethod.POST), // 查询设备充电状态
-
-    //微信
-    WX_MP_GET_PHONE("", RequestMethod.POST), // 获取手机号
-    WX_GET_ACCESS_TOKEN("", RequestMethod.POST); // 获取AccessToken
-
-    private final String api;
-    private final RequestMethod requestMethod;
-
-
-    private static class Constants {
-        static EnPlusConfig config = SpringUtil.getBean("EnPlusConfig");
-        private static final String DOMAIN = config.getApiDomain();
-    }
-}

+ 1 - 1
common/src/main/java/com/kym/common/enums/WxApi.java

@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
  */
 @AllArgsConstructor
 @Getter
-public enum WxApi implements Api {
+public enum WxApi {
 
     // 微信小程序登录
     WX_MP_LOGIN("https://api.weixin.qq.com/sns/jscode2session?grant_type=authorization_code", RequestMethod.GET),

+ 10 - 9
common/src/main/java/com/kym/common/utils/PlatformAesUtil.java

@@ -9,6 +9,7 @@ import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
 import java.security.SecureRandom;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -20,9 +21,9 @@ import java.util.logging.Logger;
  */
 public class PlatformAesUtil {
 
-    //编码方式
-    public static final String CODE_TYPE = "UTF-8";
-    //AES:加密方式   CBC:工作模式   PKCS5Padding:填充模式
+    /**
+     * AES:加密方式   CBC:工作模式   PKCS5Padding:填充模式
+     */
     private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";
     private static final String AES = "AES";
 
@@ -51,12 +52,12 @@ public class PlatformAesUtil {
             Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
 
             //偏移量
-            IvParameterSpec zeroIv = new IvParameterSpec(config.getDataSecretIv().getBytes(CODE_TYPE));
+            IvParameterSpec zeroIv = new IvParameterSpec(config.getDataSecretIv().getBytes(StandardCharsets.UTF_8));
 
-            byte[] byteContent = content.getBytes(CODE_TYPE);
+            byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);
 
             //使用加密秘钥
-            SecretKeySpec skeySpec = new SecretKeySpec(config.getDataSecret().getBytes(CODE_TYPE), AES);
+            SecretKeySpec skeySpec = new SecretKeySpec(config.getDataSecret().getBytes(StandardCharsets.UTF_8), AES);
             //初始化为加密模式的密码器
             cipher.init(Cipher.ENCRYPT_MODE, skeySpec, zeroIv);
             // 加密
@@ -86,15 +87,15 @@ public class PlatformAesUtil {
         try {
             //实例化
             Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
-            IvParameterSpec zeroIv = new IvParameterSpec(config.getDataSecretIv().getBytes(CODE_TYPE));
+            IvParameterSpec zeroIv = new IvParameterSpec(config.getDataSecretIv().getBytes(StandardCharsets.UTF_8));
 
-            SecretKeySpec skeySpec = new SecretKeySpec(config.getDataSecret().getBytes(CODE_TYPE), AES);
+            SecretKeySpec skeySpec = new SecretKeySpec(config.getDataSecret().getBytes(StandardCharsets.UTF_8), AES);
             //SecretKeySpec skeySpec = getSecretKey(key);
             cipher.init(Cipher.DECRYPT_MODE, skeySpec, zeroIv);
 
             byte[] result = cipher.doFinal(Base64.decodeBase64(content));
 
-            return new String(result, CODE_TYPE);
+            return new String(result, StandardCharsets.UTF_8);
         } catch (Exception ex) {
             Logger.getLogger(PlatformAesUtil.class.getName()).log(Level.SEVERE, null, ex);
         }

+ 12 - 8
service/src/main/java/com/kym/service/admin/impl/StationServiceImpl.java

@@ -7,7 +7,7 @@ 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.common.enums.EnPlusApi;
+import com.kym.service.enplus.EnPlusApi;
 import com.kym.common.exception.BusinessException;
 import com.kym.common.utils.CommUtil;
 import com.kym.common.utils.PlatformAesUtil;
@@ -94,7 +94,7 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
                     "LastQueryTime":""
                 }
                 """.formatted(pageNum, pageSize);
-        var response = enPlusService.platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STATION_INFO.getApi(), enPlusService.buildPlatformParams(platformName, param));
+        var response = enPlusService.platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STATION_INFO.getApi(platformName), enPlusService.buildPlatformParams(platformName, param));
         var enStations = parsePlatformResponseData(response, platformName);
         var stationList = enStations.getJSONArray("StationInfos").toJavaList(StationVo.class);
         // 我方station表数据
@@ -140,7 +140,7 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
                     "LastQueryTime":""
                 }
                 """.formatted(pageNum, pageSize);
-        var response = enPlusService.platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STATION_INFO.getApi(), enPlusService.buildPlatformParams(platformName, param));
+        var response = enPlusService.platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STATION_INFO.getApi(platformName), enPlusService.buildPlatformParams(platformName, param));
         var enStations = parsePlatformResponseData(response, platformName);
         var stationList = enStations.getJSONArray("StationInfos").toJavaList(StationVo.class);
         // 我方station表数据
@@ -229,7 +229,7 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
         // 先对站点id进行分组,单独去请求各自互联互通平台数据
         var set = new HashSet<String>();
         for (String stationId : ids) {
-            set.add(PlatformCache.INSTANCE.getPlatformNameByConnectorId(stationId));
+            set.add(PlatformCache.INSTANCE.getPlatformNameByStationId(stationId));
         }
 
         var res = new ArrayList<EnStationStatusInfo>();
@@ -239,7 +239,7 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
                         "StationIDs":["%s"]
                     }
                     """.formatted(String.join("\",\"", ids));
-            var response = enPlusService.platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STATION_STATUS.getApi(), enPlusService.buildPlatformParams(platformName, param));
+            var response = enPlusService.platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STATION_STATUS.getApi(platformName), enPlusService.buildPlatformParams(platformName, param));
             var enStationStatus = JSONObject.parseObject(PlatformAesUtil.decrypt(PlatformCache.INSTANCE.getPlatformByName(platformName),response.getData()));
             res.addAll(enStationStatus.getJSONArray("StationStatusInfos").toJavaList(EnStationStatusInfo.class));
         });
@@ -265,7 +265,7 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
                 }
                 """.formatted(stationId, startTime, endTime);
         var platformName = PlatformCache.INSTANCE.getPlatformNameByStationId(stationId);
-        var response = enPlusService.platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STATION_STATS.getApi(), enPlusService.buildPlatformParams(platformName, param));
+        var response = enPlusService.platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STATION_STATS.getApi(platformName), enPlusService.buildPlatformParams(platformName, param));
         // TODO: 2023-08-12 包装成自己的数据格式
         var enStationStats = parsePlatformResponseData(response, platformName);
         return enStationStats.getJSONObject("StationStats").toJavaObject(EnStationStatsInfo.class);
@@ -273,13 +273,14 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
 
 
     /**
-     * 拉取EN+充电站信息数据并更新本地服务器数据
+     * 拉取互联互通平台充电站信息数据并更新本地服务器数据
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void pullEnStationInfos(String stationId) {
         // 指定的站点信息
-        var stationVo = queryEnStationInfo(PlatformCache.INSTANCE.getPlatformNameByStationId(stationId), 1, 1000)
+        var platformName = PlatformCache.INSTANCE.getPlatformNameByStationId(stationId);
+        var stationVo = queryEnStationInfo(platformName, 1, 1000)
                 .stream().filter(vo -> stationId.equals(vo.getStationId())).findFirst().orElse(null);
 
         var station = new Station();
@@ -330,6 +331,9 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
         KymCache.INSTANCE.putStationId2Name(Map.of(stationVo.getStationId(), stationVo.getStationName()));
         KymCache.INSTANCE.putConnectorId2Status(connectorList.stream().collect(Collectors.toMap(ConnectorInfo::getConnectorId, ConnectorInfo::getStatus)));
 
+        PlatformCache.INSTANCE.putStationId2PlatformName(Map.of(stationVo.getStationId(), platformName));
+        PlatformCache.INSTANCE.putConnectorId2PlatformName(connectorList.stream().collect(Collectors.toMap(ConnectorInfo::getConnectorId, connectorInfo -> platformName)));
+
     }
 
 

+ 1 - 1
service/src/main/java/com/kym/service/cache/PlatformCache.java

@@ -34,7 +34,7 @@ public enum PlatformCache {
      * @param stationId
      * @return
      */
-    public static String getPlatformNameByStationId(String stationId) {
+    public String getPlatformNameByStationId(String stationId) {
         return STATION_ID_PLATFORM_NAME_MAPPING.get(stationId);
     }
 

+ 1 - 3
common/src/main/java/com/kym/common/enums/Api.java → service/src/main/java/com/kym/service/enplus/Api.java

@@ -1,4 +1,4 @@
-package com.kym.common.enums;
+package com.kym.service.enplus;
 
 import org.springframework.web.bind.annotation.RequestMethod;
 
@@ -8,6 +8,4 @@ import org.springframework.web.bind.annotation.RequestMethod;
  * @date 2023-07-08 10:34
  */
 public interface Api {
-    String getApi();
-    RequestMethod getRequestMethod();
 }

+ 43 - 0
service/src/main/java/com/kym/service/enplus/EnPlusApi.java

@@ -0,0 +1,43 @@
+package com.kym.service.enplus;
+
+import com.kym.service.cache.PlatformCache;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+
+/**
+ * @author skyline
+ * @description EN+接口
+ * @date 2023-07-29 12:33
+ */
+@AllArgsConstructor
+public enum EnPlusApi implements Api {
+
+    // 认证-获取token
+    EN_PLUS_QUERY_TOKEN("query_token", RequestMethod.POST), //获取AccessToken
+
+    // 站点
+    EN_PLUS_QUERY_STATION_INFO("query_stations_info", RequestMethod.POST), // 站点信息
+    EN_PLUS_QUERY_STATION_STATUS("query_station_status", RequestMethod.POST), // 站点状态
+    EN_PLUS_QUERY_STATION_STATS("query_station_stats", RequestMethod.POST), // 站点统计
+    //充电
+    EN_PLUS_QUERY_EQUIP_AUTH("query_equip_auth", RequestMethod.POST), // 请求设备认证
+    EN_PLUS_QUERY_EQUIP_BUSINESS_POLICY("query_equip_business_policy", RequestMethod.POST), // 查询业务策略信息
+    EN_PLUS_QUERY_START_CHARGE("query_start_charge", RequestMethod.POST), // 查询启动充电
+    EN_PLUS_QUERY_STOP_CHARGE("query_stop_charge", RequestMethod.POST), // 请求停止充电
+    EN_PLUS_QUERY_EQUIP_CHARGE_STATUS("query_equip_charge_status", RequestMethod.POST), // 查询设备充电状态
+
+    //微信
+    WX_MP_GET_PHONE("", RequestMethod.POST), // 获取手机号
+    WX_GET_ACCESS_TOKEN("", RequestMethod.POST); // 获取AccessToken
+
+    private final String api;
+    private final RequestMethod requestMethod;
+
+    public String getApi(String platformName) {
+        var config = PlatformCache.INSTANCE.getPlatformByName(platformName);
+        return config.getApiDomain() + api;
+    }
+
+}

+ 19 - 23
service/src/main/java/com/kym/service/enplus/impl/PlatformApiServiceImpl.java

@@ -7,7 +7,7 @@ import cn.hutool.crypto.digest.HmacAlgorithm;
 import com.alibaba.fastjson2.JSONObject;
 import com.kym.common.annotation.DynamicCache;
 import com.kym.common.constant.ResponseEnum;
-import com.kym.common.enums.EnPlusApi;
+import com.kym.service.enplus.EnPlusApi;
 import com.kym.common.exception.BusinessException;
 import com.kym.common.exception.EnPushException;
 import com.kym.common.utils.CommUtil;
@@ -39,13 +39,6 @@ public class PlatformApiServiceImpl implements PlatformApiService {
     static OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder().build();
     private final RedisTemplate<String, String> redisTemplate;
 
-    @Value("${en-plus.operatorId}")
-    private String OperatorId;
-    @Value("${en-plus.operatorSecret}")
-    private String OperatorSecret;
-    @Value("${en-plus.sigSecret}")
-    private String SigSecret;
-
     public PlatformApiServiceImpl(RedisTemplate<String, String> redisTemplate) {
         this.redisTemplate = redisTemplate;
     }
@@ -117,7 +110,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
      */
     @Override
     public String queryPlatformToken(String platformName) {
-        log.info("查询互联互通平台token:{}", platformName);
+        log.info("查询互联互通平台{}token", platformName);
         var token = redisTemplate.opsForValue().get(RedisKeys.EN_PLUS_TOKEN + platformName);
         if (CommUtil.isNotEmptyAndNull(token)) {
             // 不同平台不同key
@@ -129,11 +122,11 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "OperatorID":"%s",
                     "OperatorSecret":"%s"
                 }
-                """.formatted(OperatorId, OperatorSecret);
+                """.formatted(PlatformCache.INSTANCE.getPlatformByName(platformName).getOperatorId(), PlatformCache.INSTANCE.getPlatformByName(platformName).getOperatorSecret());
 
         var requestParams = buildPlatformParams(platformName, data);
 
-        var response = platformGetToken(EnPlusApi.EN_PLUS_QUERY_TOKEN.getApi(), requestParams);
+        var response = platformGetToken(EnPlusApi.EN_PLUS_QUERY_TOKEN.getApi(platformName), requestParams);
 
         if (response != null && 0 == response.getRet()) {
             // 解密Data获取token
@@ -177,15 +170,17 @@ public class PlatformApiServiceImpl implements PlatformApiService {
      */
     @Override
     public String buildPlatformParams(String platformName, String params) {
+        var platform = PlatformCache.INSTANCE.getPlatformByName(platformName);
         // 使用DataSecret对data加密
-        var dataStr = PlatformAesUtil.encrypt(PlatformCache.INSTANCE.getPlatformByName(platformName), params);
+//        var dataStr = PlatformAesUtil.encrypt(platform, params);
+        var dataStr = PlatformAesUtil.encrypt(platform, params);
         // 时间戳
         var timeStamp = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN);
         // 自增序列
         var seq = timeStamp.substring(timeStamp.length() - 4);
         // 使用SigSecret以HMAC-MD5算法对消息体签名(签名顺序:OperatorId、Data、TimeStamp、Seq)
-        var signString = OperatorId + dataStr + timeStamp + seq;
-        HMac mac = new HMac(HmacAlgorithm.HmacMD5, SigSecret.getBytes());
+        var signString = platform.getOperatorId() + dataStr + timeStamp + seq;
+        HMac mac = new HMac(HmacAlgorithm.HmacMD5, platform.getSigSecret().getBytes());
         // 签名(转为大写)
         var sign = mac.digestHex(signString).toUpperCase();
         return """
@@ -196,7 +191,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "Seq":"%s",
                     "Sig":"%s"
                 }
-                """.formatted(OperatorId, dataStr, timeStamp, seq, sign);
+                """.formatted(platform.getOperatorId(), dataStr, timeStamp, seq, sign);
     }
 
     /**
@@ -208,6 +203,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
      */
     @Override
     public String signValidation(String platformName, JSONObject json) {
+        var platform = PlatformCache.INSTANCE.getPlatformByName(platformName);
         // 验签 解密数据
         var OperatorID = json.getString("OperatorID");
         var Data = json.getString("Data");
@@ -215,12 +211,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, SigSecret.getBytes());
+        HMac mac = new HMac(HmacAlgorithm.HmacMD5, platform.getSigSecret().getBytes());
         // 签名(转为大写)
         var sign = mac.digestHex(signString).toUpperCase();
         if (sign.equals(Sig)) {
             // 解密数据
-            return PlatformAesUtil.decrypt(PlatformCache.INSTANCE.getPlatformByName(platformName), Data);
+            return PlatformAesUtil.decrypt(platform, Data);
         } else {
             // 验签失败
             PlatformResponse enResponse = new PlatformResponse();
@@ -249,7 +245,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "ConnectorID":"%s"
                 }
                 """.formatted(equipAuthSeq, connectorId);
-        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_EQUIP_AUTH.getApi(), buildPlatformParams(platformName, param));
+        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_EQUIP_AUTH.getApi(platformName), buildPlatformParams(platformName, param));
 
         return parsePlatformResponseData(response, platformName);
     }
@@ -272,7 +268,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "ConnectorID":"%s"
                 }
                 """.formatted(equipBizSeq, connectorId);
-        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_EQUIP_BUSINESS_POLICY.getApi(), buildPlatformParams(platformName, param));
+        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_EQUIP_BUSINESS_POLICY.getApi(platformName), buildPlatformParams(platformName, param));
         return parsePlatformResponseData(response, platformName);
     }
 
@@ -296,7 +292,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "amount":"%d"
                 }
                 """.formatted(startChargeSeq, connectorId, qrCode, amount);
-        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_START_CHARGE.getApi(), buildPlatformParams(platformName, param));
+        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_START_CHARGE.getApi(platformName), buildPlatformParams(platformName, param));
         return parsePlatformResponseData(response, platformName);
     }
 
@@ -314,7 +310,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "StartChargeSeq":"%s"
                 }
                 """.formatted(startChargeSeq);
-        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_EQUIP_CHARGE_STATUS.getApi(), buildPlatformParams(platformName, param));
+        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_EQUIP_CHARGE_STATUS.getApi(platformName), buildPlatformParams(platformName, param));
         return parsePlatformResponseData(response, platformName);
     }
 
@@ -334,7 +330,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "amount":%d
                 }
                 """.formatted(startChargeSeq, amount);
-        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_EQUIP_CHARGE_STATUS.getApi(), buildPlatformParams(platformName, param));
+        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_EQUIP_CHARGE_STATUS.getApi(platformName), buildPlatformParams(platformName, param));
         return parsePlatformResponseData(response, platformName);
     }
 
@@ -354,7 +350,7 @@ public class PlatformApiServiceImpl implements PlatformApiService {
                     "ConnectorID":"%s"
                 }
                 """.formatted(startChargeSeq, connectorId);
-        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STOP_CHARGE.getApi(), buildPlatformParams(platformName, param));
+        var response = platformPost(platformName, EnPlusApi.EN_PLUS_QUERY_STOP_CHARGE.getApi(platformName), buildPlatformParams(platformName, param));
         return parsePlatformResponseData(response, platformName);
     }