소스 검색

1.一键上下班功能新增密码修改同步

jingyuanchao 1 년 전
부모
커밋
f2e845cfa3

+ 326 - 0
soc-common/soc-common-core/src/main/java/com/xunmei/common/core/utils/RsaHelper.java

@@ -0,0 +1,326 @@
+package com.xunmei.common.core.utils;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+/**
+ * @author hms
+ */
+public class RsaHelper {
+
+    public static String publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyJdVXw+TvnFnE2ElRmJflkFO20wSjJzS+XV887at9jTKa+EhpSg7aCNgCcFQfCEVpHVKegR4s02+4RH4q+y0gP/yIjAdyKAh16gC9NiM83WpN/PfBCOon55bIJI5G0OBi1I0el+3rpBqtRRzlRfiOXi4C6pmO0ayVmP5rVNASsQIDAQAB";
+
+    public static String privateKeyString = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALIl1VfD5O+cWcTYSVGYl+WQU7bTBKMnNL5dXzztq32NMpr4SGlKDtoI2AJwVB8IRWkdUp6BHizTb7hEfir7LSA//IiMB3IoCHXqAL02Izzdak3898EI6ifnlsgkjkbQ4GLUjR6X7eukGq1FHOVF+I5eLgLqmY7RrJWY/mtU0BKxAgMBAAECgYB5cn1c1blO+GHiZiilrcdvwtKvQnBY4bN9S55PpR9R+l5Tc4u567jwPzMzhmxys2rOXCUk1ZVCrentzxPMLWv2+zHo+DdlgszpQcVSgFyPV+wFDcPxLcFRt3VXJG7wWtzs0iX1IjAa36X8vhwTDgxAXbiuNeDH2L7716inh+8IAQJBANj8MX84KRE3WVV2hTvx/rwTwtkFugzl3wBKjqCx1vZoLs2LgEriRTPUtDSg8gpi3LN4QbgsTK903v4eL1NfO0ECQQDSLfXhwNMnyU6k48OJS8YWFpS15yWD2L2a/hO158zuTJDy1SiV1LekH7fJ96y4VBKsjIuzFH4SLj6AuMtjEytxAkBPROK4PUYTegryw9esrJ2JDBcUvZjYeWnca2BrqEyFvE3M3XfC46KwarZiu6Fw1ekWz4oCxHxHZQTKBTD43kOBAkB6UP0TkKBSOzllhJe7QznYiPOqmQagIHbXyJ2381q0JCMG7z5bVBw7i6nuBBGkhGkJuhFi+r4T3o3JY8IZuoJBAkAMSruTTxnoAAuhwNKfGBSSyQ99KD1qIHhIPnqtfx9UhaR6diDBSMNknRP9PK6ZW9xy90CJ3jq4/zalIjAVqzUX";
+
+
+    public static String subDecodeStr(String str) throws Exception {
+        String[] strs = str.split(",");
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < strs.length; i++) {
+            sb.append(decodeStr(strs[i]));
+        }
+        return sb.toString();
+    }
+
+    public static String encodeStr(String content) {
+        int keySize = 1024;
+        RsaHelper rsa = new RsaHelper();
+        KeyPairInfo info = rsa.getKeyPair(keySize); //每次调用的公钥 私钥都一样
+        int enSegmentSize = 117;//keysize=1024时,分段不能大于117 ;keysize>=2048时,分段不能大于keySize/8+128;
+        String ciphertext = rsa.encipher(content, info.getPublicKey(), enSegmentSize);
+        return ciphertext;
+    }
+
+    public static String decodeStr(String content) throws Exception {
+        int keySize = 1024;
+        RsaHelper rsa = new RsaHelper();
+        KeyPairInfo info = rsa.getKeyPair(keySize); //每次调用的公钥 私钥都一样
+        int deSegmentSize = 128;//等于keySize/8
+        String deTxt = rsa.decipher(content, info.getPrivateKey(), deSegmentSize);
+        return deTxt;
+    }
+
+    /**
+     * 生成公钥、私钥对(keysize=1024)
+     *
+     * @return
+     */
+    public KeyPairInfo getKeyPair() {
+        return getKeyPair(1024);
+    }
+
+    /**
+     * 生成公钥、私钥对
+     *
+     * @param keySize
+     * @return
+     */
+    public KeyPairInfo getKeyPair(int keySize) {
+        try {
+            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
+            // 初始化密钥对生成器,密钥大小一般要大于1024位,
+//			String aa=String.valueOf(new Random().nextInt(999999999));
+//			SecureRandom random = new SecureRandom(aa.getBytes()); //?????
+//			keyPairGen.initialize(keySize,random);
+            keyPairGen.initialize(keySize);
+            // 生成一个密钥对,保存在keyPair中
+            KeyPair keyPair = keyPairGen.generateKeyPair();
+            // 得到私钥
+            RSAPrivateKey oraprivateKey = (RSAPrivateKey) keyPair.getPrivate();
+            // 得到公钥
+            RSAPublicKey orapublicKey = (RSAPublicKey) keyPair.getPublic();
+
+            KeyPairInfo pairInfo = new KeyPairInfo(keySize);
+            //公钥
+            byte[] publicKeybyte = orapublicKey.getEncoded();
+//			String publicKeyString = Base64.encodeBase64String(publicKeybyte);
+            pairInfo.setPublicKey(publicKeyString);
+            //私钥
+            byte[] privateKeybyte = oraprivateKey.getEncoded();
+//			String privateKeyString = Base64.encodeBase64String(privateKeybyte);
+            pairInfo.setPrivateKey(privateKeyString);
+
+            return pairInfo;
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 获取公钥对象
+     *
+     * @param publicKeyBase64
+     * @return
+     * @throws InvalidKeySpecException
+     * @throws NoSuchAlgorithmException
+     */
+    public PublicKey getPublicKey(String publicKeyBase64)
+            throws InvalidKeySpecException, NoSuchAlgorithmException {
+
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        X509EncodedKeySpec publicpkcs8KeySpec =
+                new X509EncodedKeySpec(Base64.decodeBase64(publicKeyBase64));
+        PublicKey publicKey = keyFactory.generatePublic(publicpkcs8KeySpec);
+        return publicKey;
+    }
+
+    /**
+     * 获取私钥对象
+     *
+     * @param privateKeyBase64
+     * @return
+     * @throws NoSuchAlgorithmException
+     * @throws InvalidKeySpecException
+     */
+    public PrivateKey getPrivateKey(String privateKeyBase64)
+            throws NoSuchAlgorithmException, InvalidKeySpecException {
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        PKCS8EncodedKeySpec privatekcs8KeySpec =
+                new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyBase64));
+        PrivateKey privateKey = keyFactory.generatePrivate(privatekcs8KeySpec);
+        return privateKey;
+    }
+
+    /**
+     * 使用共钥加密
+     *
+     * @param content         待加密内容
+     * @param publicKeyBase64 公钥 base64 编码
+     * @return 经过 base64 编码后的字符串
+     */
+    public String encipher(String content, String publicKeyBase64) {
+        return encipher(content, publicKeyBase64, -1);
+    }
+
+    /**
+     * 使用共钥加密(分段加密)
+     *
+     * @param content         待加密内容
+     * @param publicKeyBase64 公钥 base64 编码
+     * @param segmentSize     分段大小,一般小于 keySize/8(段小于等于0时,将不使用分段加密)
+     * @return 经过 base64 编码后的字符串
+     */
+    public String encipher(String content, String publicKeyBase64, int segmentSize) {
+        try {
+            PublicKey publicKey = getPublicKey(publicKeyBase64);
+            return encipher(content, publicKey, segmentSize);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 分段加密
+     *
+     * @param ciphertext  密文
+     * @param key         加密秘钥
+     * @param segmentSize 分段大小,<=0 不分段
+     * @return
+     */
+    public String encipher(String ciphertext, Key key, int segmentSize) {
+        try {
+            // 用公钥加密
+            byte[] srcBytes = ciphertext.getBytes();
+
+            // Cipher负责完成加密或解密工作,基于RSA
+            Cipher cipher = Cipher.getInstance("RSA");
+            // 根据公钥,对Cipher对象进行初始化
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+            byte[] resultBytes = null;
+
+            if (segmentSize > 0)
+                resultBytes = cipherDoFinal(cipher, srcBytes, segmentSize); //分段加密
+            else
+                resultBytes = cipher.doFinal(srcBytes);
+
+            String base64Str = Base64.encodeBase64String(resultBytes);
+            return base64Str;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 分段大小
+     *
+     * @param cipher
+     * @param srcBytes
+     * @param segmentSize
+     * @return
+     * @throws IllegalBlockSizeException
+     * @throws BadPaddingException
+     * @throws IOException
+     */
+    private byte[] cipherDoFinal(Cipher cipher, byte[] srcBytes, int segmentSize)
+            throws IllegalBlockSizeException, BadPaddingException, IOException {
+        if (segmentSize <= 0)
+            throw new RuntimeException("分段大小必须大于0");
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int inputLen = srcBytes.length;
+        int offSet = 0;
+        byte[] cache;
+        int i = 0;
+        // 对数据分段解密
+        while (inputLen - offSet > 0) {
+            if (inputLen - offSet > segmentSize) {
+                cache = cipher.doFinal(srcBytes, offSet, segmentSize);
+            } else {
+                cache = cipher.doFinal(srcBytes, offSet, inputLen - offSet);
+            }
+            out.write(cache, 0, cache.length);
+            i++;
+            offSet = i * segmentSize;
+        }
+        byte[] data = out.toByteArray();
+        out.close();
+        return data;
+    }
+
+    /**
+     * 使用私钥解密
+     *
+     * @param contentBase64    待加密内容,base64 编码
+     * @param privateKeyBase64 私钥 base64 编码
+     * @return
+     * @segmentSize 分段大小
+     */
+    public String decipher(String contentBase64, String privateKeyBase64) throws Exception {
+        return decipher(contentBase64, privateKeyBase64, -1);
+    }
+
+    /**
+     * 使用私钥解密(分段解密)
+     *
+     * @param contentBase64    待加密内容,base64 编码
+     * @param privateKeyBase64 私钥 base64 编码
+     * @return
+     * @segmentSize 分段大小
+     */
+    public String decipher(String contentBase64, String privateKeyBase64, int segmentSize) throws Exception {
+        PrivateKey privateKey = getPrivateKey(privateKeyBase64);
+        return decipher(contentBase64, privateKey, segmentSize);
+    }
+
+    /**
+     * 分段解密
+     *
+     * @param contentBase64 密文
+     * @param key           解密秘钥
+     * @param segmentSize   分段大小(小于等于0不分段)
+     * @return
+     */
+    public String decipher(String contentBase64, Key key, int segmentSize) throws Exception {
+        // 用私钥解密
+        byte[] srcBytes = Base64.decodeBase64(contentBase64);
+        // Cipher负责完成加密或解密工作,基于RSA
+        Cipher deCipher = Cipher.getInstance("RSA");
+        // 根据公钥,对Cipher对象进行初始化
+        deCipher.init(Cipher.DECRYPT_MODE, key);
+        byte[] decBytes = null;//deCipher.doFinal(srcBytes);
+        if (segmentSize > 0)
+            decBytes = cipherDoFinal(deCipher, srcBytes, segmentSize); //分段加密
+        else
+            decBytes = deCipher.doFinal(srcBytes);
+
+        String decrytStr = new String(decBytes);
+        return decrytStr;
+    }
+
+    /**
+     * 秘钥对
+     */
+    public class KeyPairInfo {
+        public KeyPairInfo(int keySize) {
+            setKeySize(keySize);
+        }
+
+        public KeyPairInfo(String publicKey, String privateKey) {
+            setPrivateKey(privateKey);
+            setPublicKey(publicKey);
+        }
+
+        String privateKey;
+        String publicKey;
+        int keySize = 0;
+
+        public String getPrivateKey() {
+            return privateKey;
+        }
+
+        public void setPrivateKey(String privateKey) {
+            this.privateKey = privateKey;
+        }
+
+        public String getPublicKey() {
+            return publicKey;
+        }
+
+        public void setPublicKey(String publicKey) {
+            this.publicKey = publicKey;
+        }
+
+        public int getKeySize() {
+            return keySize;
+        }
+
+        public void setKeySize(int keySize) {
+            this.keySize = keySize;
+        }
+    }
+
+}

+ 4 - 0
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/websocket/constant/WebSocketConstants.java

@@ -168,6 +168,10 @@ public interface WebSocketConstants {
      * 上下班操作数据
      */
     String WORK_OPERATION = "workOperation";
+    /**
+     * 修改上下班操作密码
+     */
+    String PASSWORD_CHANGE = "passwordChange";
 
     /**
      * 全量workRule

+ 7 - 1
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/work/service/impl/IotDayWorkOperationServiceImpl.java

@@ -8,6 +8,7 @@ import com.xunmei.common.core.constant.Constants;
 import com.xunmei.common.core.domain.iot.domain.IotServerInfo;
 import com.xunmei.common.core.domain.work.domain.IotDayWorkOperation;
 import com.xunmei.common.core.domain.work.dto.WorkOperationReq;
+import com.xunmei.common.core.utils.RsaHelper;
 import com.xunmei.host.websocket.constant.WebSocketConstants;
 import com.xunmei.host.websocket.dto.WebsocketExecuteReq;
 import com.xunmei.host.websocket.enums.ProductEnums;
@@ -77,7 +78,12 @@ public class IotDayWorkOperationServiceImpl extends ServiceImpl<IotDayWorkOperat
         }
         return null;
     }
-
+    public static void main(String[] args) throws Exception {
+        final String encodeStr = RsaHelper.encodeStr("123456");
+        System.out.println(encodeStr);
+        final String decodeStr = RsaHelper.decodeStr(encodeStr);
+        System.out.println(decodeStr);
+    }
     @Override
     public IotDayWorkOperation findByHostDataIdAndIotCode(Long hostDataId, Long hostDataOperationId, String iotCode) {
         LambdaQueryWrapper<IotDayWorkOperation> wrapper = new LambdaQueryWrapper<>();

+ 39 - 2
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/work/service/impl/IotDayWorkServiceImpl.java

@@ -8,6 +8,8 @@ import com.xunmei.common.core.constant.Constants;
 import com.xunmei.common.core.domain.iot.domain.IotServerInfo;
 import com.xunmei.common.core.domain.work.domain.IotDayWork;
 import com.xunmei.common.core.domain.work.dto.DayWorKReq;
+import com.xunmei.common.core.utils.RsaHelper;
+import com.xunmei.host.server.service.IotServerInfoService;
 import com.xunmei.host.websocket.constant.WebSocketConstants;
 import com.xunmei.host.websocket.dto.WebsocketExecuteReq;
 import com.xunmei.host.websocket.enums.ProductEnums;
@@ -19,6 +21,8 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+import java.util.Map;
 import java.util.StringJoiner;
 
 /**
@@ -31,6 +35,8 @@ import java.util.StringJoiner;
  */
 @Service
 public class IotDayWorkServiceImpl extends ServiceImpl<IotDayWorkMapper, IotDayWork> implements IotDayWorkService, RouterService {
+    @Resource
+    IotServerInfoService serverInfoService;
 
     @Override
     public ProductEnums product() {
@@ -42,6 +48,7 @@ public class IotDayWorkServiceImpl extends ServiceImpl<IotDayWorkMapper, IotDayW
         StringJoiner sj = new StringJoiner(",");
         //上下班主表数据
         sj.add(WebSocketConstants.WORK);
+        sj.add(WebSocketConstants.PASSWORD_CHANGE);
 
         return sj.toString();
     }
@@ -49,13 +56,28 @@ public class IotDayWorkServiceImpl extends ServiceImpl<IotDayWorkMapper, IotDayW
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Object execute(WebsocketExecuteReq req) {
+        final String event = req.getEvent();
+        switch (event) {
+            case WebSocketConstants.WORK:
+                dealIotDayWorkData(req);
+                break;
+            case WebSocketConstants.PASSWORD_CHANGE:
+                dealPassWordChange(req);
+                break;
+            default:
+                break;
+        }
+        return null;
+    }
+
+    private void dealIotDayWorkData(WebsocketExecuteReq req) {
         Object data = req.getData();
         LogUtils.SOCKET_WORK_DATA.info("接收到一键上下班主表数据:{}", data);
         final IotServerInfo serverInfo = req.getServerInfo();
         DayWorKReq work = JSON.parseObject(data.toString(), DayWorKReq.class);
         IotDayWork dayWork = findByHostDataIdAndIotCode(work.getId(), req.getServerInfo().getIotCode());
         if (dayWork != null) {
-            BeanUtils.copyProperties(work, dayWork,"id");
+            BeanUtils.copyProperties(work, dayWork, "id");
             dayWork.setHostDataId(work.getId());
             updateById(dayWork);
         } else {
@@ -69,7 +91,22 @@ public class IotDayWorkServiceImpl extends ServiceImpl<IotDayWorkMapper, IotDayW
             dayWork.setOrgPath(serverInfo.getOrgPath());
             this.save(dayWork);
         }
-        return null;
+    }
+
+    private void dealPassWordChange(WebsocketExecuteReq req) {
+        Object data = req.getData();
+        LogUtils.SOCKET_WORK_DATA.info("接收到上下班操作密码修改数据:{}", data);
+        final IotServerInfo serverInfo = req.getServerInfo();
+        try {
+            final Map map = JSON.parseObject(data.toString(), Map.class);
+            final String password = (String) map.get("password");
+            serverInfo.setPassword(RsaHelper.decodeStr(password));
+            serverInfoService.updateById(serverInfo);
+        } catch (Exception e) {
+
+            LogUtils.SOCKET_WORK_DATA.error("上下班操作密码修改失败:{}", e.getMessage());
+            throw new RuntimeException(e);
+        }
     }
 
     @Override