Browse Source

龙洞堡机场增加黑名单加密逻辑

王鑫刚 5 months ago
parent
commit
07511539e7

+ 103 - 0
src/main/java/com/yx/face/boot/uitls/AppUtils.java

@@ -0,0 +1,103 @@
+package com.yx.face.boot.uitls;
+
+
+import cn.hutool.core.util.RandomUtil;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.UUID;
+
+/**
+ * @author shisl
+ * @package com.yx.face.boot.uitls
+ * @class AppUtils
+ * @date 2022/10/25 下午6:22
+ * @description appKey appSecret 生成工具类
+ */
+public class AppUtils {
+    private final static String APP_KEY_PREFIX = "hh";
+    private final static String SERVER_NAME = "hanghui_api_nqj##361";
+    private final static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
+            "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
+            "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
+            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
+            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+            "W", "X", "Y", "Z"};
+
+    /**
+     * <p>
+     * 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个。
+     * 本算法利用62个可打印字符,通过随机生成32位UUID,由于UUID都为十六进制,
+     * 所以将UUID + 时间戳 分成9组,每5个为一组,然后通过模62操作,结果作为索引取出字符,
+     * 这样重复率大大降低。
+     * 经测试,在生成一千万个数据也没有出现重复,完全满足大部分需求。
+     * </p>
+     *
+     * @return
+     */
+    public static String getAppKey() {
+        StringBuffer shortBuffer = new StringBuffer().append(APP_KEY_PREFIX);
+        String uuid = UUID.randomUUID().toString().replace("-", "") + System.currentTimeMillis();
+        for (int i = 0; i < 9; i++) {
+            String str = uuid.substring(i * 5, i * 5 + 5);
+            int x = Integer.parseInt(str, 16);
+            shortBuffer.append(chars[x % 0x3E]);
+        }
+        return shortBuffer.toString();
+    }
+
+    /**
+     * 算法sha1生成AppSecret
+     *
+     * @param appKey
+     * @return
+     */
+    public static String getAppSecret(String appKey) {
+        try {
+
+            StringBuffer sb = new StringBuffer();
+            String uuid = UUID.randomUUID().toString();
+            sb.append(appKey).append(SERVER_NAME).append(uuid);
+
+            String str = sb.toString();
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            md.update(str.getBytes());
+            byte[] digest = md.digest();
+
+            StringBuffer hexstr = new StringBuffer();
+            String shaHex = "";
+            for (int i = 0; i < digest.length; i++) {
+                shaHex = Integer.toHexString(digest[i] & 0xFF);
+                if (shaHex.length() < 2) {
+                    hexstr.append(0);
+                }
+                hexstr.append(shaHex);
+            }
+            return hexstr.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return appKey;
+    }
+
+    /**
+     * 返回一个定长的随机字符串(只包含大小写字母、数字)
+     *
+     * @return 随机字符串
+     */
+    public static String getPrivateKey() {
+
+        return RandomUtil.randomString(16).toLowerCase();
+    }
+
+    public static void main(String[] args) {
+        String appKey = getAppKey();
+        String appSecret = getAppSecret(appKey);
+        System.out.println("--->time: " + System.currentTimeMillis());
+
+        System.out.println("--->appKey: " + appKey);
+        System.out.println("--->appSecret: " + appSecret);
+        System.out.println("--->privateKey: " + getPrivateKey());
+
+    }
+}

+ 89 - 0
src/main/java/com/yx/face/boot/uitls/Sm4Util.java

@@ -0,0 +1,89 @@
+package com.yx.face.boot.uitls;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.SmUtil;
+import cn.hutool.crypto.symmetric.SymmetricCrypto;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.charset.Charset;
+
+@Slf4j
+public class Sm4Util {
+
+    /**
+     * 加密
+     *
+     * @param privateKey 管理员提供
+     * @param str
+     * @return
+     */
+    public static String encrypt(final String privateKey, final String str) {
+      if (StrUtil.isBlank((CharSequence) str)) {
+        return "";
+      }
+      
+       try {
+            SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", privateKey.getBytes());
+            return sm4.encryptHex(str, Charset.forName("UTF-8"));
+        } catch (Exception e) {
+            log.error("加密失败", e);
+            return null;
+        }
+    }
+
+    /**
+     * 解密
+     *
+     * @param privateKey 管理员提供
+     * @param str
+     * @return
+     */
+    public static String decrypt(final String privateKey, final String str) {
+        if (StrUtil.isBlank((CharSequence) str)) {
+            return null;
+        }
+        try {
+            SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", privateKey.getBytes());
+            return sm4.decryptStr(str, Charset.forName("UTF-8"));
+        } catch (Exception e) {
+            log.error("解密失败", e);
+            return null;
+        }
+    }
+  
+   /**
+     * 验证签名
+     *
+     * @param appKey
+     * @param appSecret
+     * @param sign
+     * @param timestamp
+     * @return
+     */
+    public static Boolean checkSign(String appKey, String appSecret, String sign, String timestamp) {
+        String dbSign = SecureUtil.md5(new StringBuilder().append(appKey)
+                .append(appSecret)
+                .append(timestamp).toString()).toLowerCase();
+        if (!dbSign.equals(sign)) {
+            return Boolean.FALSE;
+        }
+        return Boolean.TRUE;
+    }
+
+    /**
+     * 获取签名
+     *
+     * @param appKey
+     * @param appSecret
+     * @param timestamp
+     * @return
+     */
+    public static String getSign(String appKey, String appSecret, String timestamp) {
+        String sign = SecureUtil.md5(new StringBuilder().append(appKey)
+                .append(appSecret)
+                .append(timestamp).toString()).toLowerCase();
+        return sign;
+    }
+  
+ }

+ 7 - 0
src/main/java/com/yx/face/controller/admin/UserBlackTaskController.java

@@ -100,5 +100,12 @@ public class UserBlackTaskController {
         }
         return userBlackTaskService.getBlackList(dto);
     }
+    @ApiOperation("设备获取黑名单列表-加密")
+    @PostMapping("device/encry/getBlackList")
+    @ApiOperationSupport(order = 90)
+    @Authority(required = false)
+    public RestResult<ThirdPlatformSm4DTO> getEncryBlackList(@RequestBody @Valid ThirdPlatformSm4DTO dto) {
+        return userBlackTaskService.getEncryBlackList(dto);
+    }
 
 }

+ 13 - 0
src/main/java/com/yx/face/model/black/DeviceBlackEncryVo.java

@@ -0,0 +1,13 @@
+package com.yx.face.model.black;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.Objects;
+
+@Data
+@AllArgsConstructor
+public class DeviceBlackEncryVo {
+
+    private String content;//加密数据
+}

+ 25 - 0
src/main/java/com/yx/face/model/black/ThirdPlatformSm4DTO.java

@@ -0,0 +1,25 @@
+package com.yx.face.model.black;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+
+@ApiModel("第三方接口查询加密内容DTO")
+@Data
+@Accessors(chain = true)
+public class ThirdPlatformSm4DTO {
+
+    @ApiModelProperty(value = "签名md5(appKey+appSecret+timestamp) 小写32位")
+    private String sign;
+
+    @ApiModelProperty(value = "时间戳毫秒 1666881956513")
+    private Long reqTimestamp;
+
+    @ApiModelProperty(value = "加密后的内容")
+    private String bizContent;
+
+
+}
+

+ 1 - 0
src/main/java/com/yx/face/service/UserBlackTaskService.java

@@ -26,4 +26,5 @@ public interface UserBlackTaskService extends IService<UserBlackTask> {
     IPage<UserBlackVo> userGetPageList(RestDTO<UserBlackSearch> dto);
     Boolean userDelete(Long userBlackListId);
     RestResult<List<DeviceBlackVo>> getBlackList(DeviceBlackDto dto);
+    RestResult<ThirdPlatformSm4DTO> getEncryBlackList(ThirdPlatformSm4DTO dto);
 }

+ 58 - 1
src/main/java/com/yx/face/service/impl/UserBlackTaskServiceImpl.java

@@ -1,13 +1,19 @@
 package com.yx.face.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.codec.Base64;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.DesensitizedUtil;
 import cn.hutool.core.util.IdcardUtil;
+import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.AES;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -15,7 +21,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.yx.face.boot.restful.RestDTO;
 import com.yx.face.boot.restful.RestResult;
+import com.yx.face.boot.uitls.AppTokenUtil;
 import com.yx.face.boot.uitls.ClassUtil;
+import com.yx.face.boot.uitls.Sm4Util;
 import com.yx.face.dao.AdminDao;
 import com.yx.face.dao.FaceDeviceDao;
 import com.yx.face.dao.UserBlackListDao;
@@ -350,7 +358,56 @@ public class UserBlackTaskServiceImpl extends ServiceImpl<UserBlackTaskDao, User
                         .in(UserBlackList::getAdminId, adminLessVos.stream().map(AdminLessVo::getAdminId).collect(Collectors.toList()))
         );
 
-        List<DeviceBlackVo> blackVos = userBlackListList.stream().map(p -> new DeviceBlackVo(p.getName(), p.getPhone(), p.getIdNumber())).distinct().collect(Collectors.toList());
+        List<DeviceBlackVo> blackVos = userBlackListList.stream().map(p -> new DeviceBlackVo(p.getName(), p.getIdNumber(), p.getPhone())).distinct().collect(Collectors.toList());
         return RestResult.ok(blackVos);
     }
+
+
+    private static final String appKey = "hhNgnrVy6GB";
+    private static final String appSecret = "e166f060d3ff50248b7bb914aa4e3a9bdd970cf0";
+    private static final String privateKey = "44wdisqvg7lm4qd8";
+    @Override
+    public RestResult<ThirdPlatformSm4DTO> getEncryBlackList(ThirdPlatformSm4DTO dto) {
+
+        //校验签名
+        Boolean checkSign = Sm4Util.checkSign(appKey, appSecret, dto.getSign(), String.valueOf(dto.getReqTimestamp()));
+        ClassUtil.throwBusinessException(!checkSign, "联动平台三方接口返回签名错误");
+        //解密数据
+        String decrypt = Sm4Util.decrypt(privateKey, dto.getBizContent());
+
+        DeviceBlackDto deviceBlackDto = JSON.parseObject(decrypt, DeviceBlackDto.class);
+        deviceBlackDto.setToken(AppTokenUtil.getTokens().get(0));
+//
+//
+//
+        RestResult<List<DeviceBlackVo>> blackList = this.getBlackList(deviceBlackDto);
+        List<DeviceBlackVo> data = blackList.getData();
+        ThirdPlatformSm4DTO thirdPlatformSm4DTO = new ThirdPlatformSm4DTO();
+        long currentTimeMillis = System.currentTimeMillis();
+        thirdPlatformSm4DTO.setReqTimestamp(currentTimeMillis);
+        thirdPlatformSm4DTO.setSign(Sm4Util.getSign(appKey, appSecret, String.valueOf(currentTimeMillis)));
+        thirdPlatformSm4DTO.setBizContent(Sm4Util.encrypt(privateKey, JSONObject.toJSONString(data)));
+        return RestResult.ok(thirdPlatformSm4DTO);
+    }
+
+    public static void main(String[] args) {
+        DeviceBlackDto data = new DeviceBlackDto();
+        data.setSn("224F010T01400584");
+
+
+        ThirdPlatformSm4DTO thirdPlatformSm4DTO = new ThirdPlatformSm4DTO();
+        long currentTimeMillis = System.currentTimeMillis();
+        thirdPlatformSm4DTO.setReqTimestamp(currentTimeMillis);
+        thirdPlatformSm4DTO.setSign(Sm4Util.getSign(appKey, appSecret, String.valueOf(currentTimeMillis)));
+        thirdPlatformSm4DTO.setBizContent(Sm4Util.encrypt(privateKey, JSONObject.toJSONString(data)));
+        System.out.println(JSONObject.toJSONString(thirdPlatformSm4DTO));
+//        byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
+//转成字符串
+//        String sey = Base64.encode(key);
+//        String key = RandomUtil.randomString(16);
+//        System.out.println(key);
+
+        System.out.println(Sm4Util.decrypt(privateKey, "2bc6930c24b82d803257569ed77c1d9e08ebfce4c663f5ce5ba911c8810294717f52d8006ed3cd6f582ad9d64065a558f89a74cf7a353dbbca0999548cd37c11baa4effbf75fced0e9bda8f7ec55424fad7f3effcd3070ed0dae4a5dcbd50bbd759d6174fa0fb9dc826a760655fd9ea53f117c521af96ef2432549382a2894aede74cdaec1c4f4d5ee38d4819aed1b64446d841ac93523808e1e2429bbcffd15"));
+    }
+
 }