Browse Source

发送mqtt增加认证

luoguangyi 3 years ago
parent
commit
4e0539925a

+ 6 - 0
pom.xml

@@ -136,6 +136,12 @@
             <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
             <version>1.2.5</version>
         </dependency>
+        <!--mqtt认证-->
+        <dependency>
+            <groupId>bouncycastle</groupId>
+            <artifactId>bcprov-jdk15</artifactId>
+            <version>140</version>
+        </dependency>
     </dependencies>
     <build>
         <finalName>${project.artifactId}</finalName>

+ 13 - 4
src/main/java/com/persagy/simulator_gaopin/Constant.java

@@ -1,9 +1,7 @@
 package com.persagy.simulator_gaopin;
 
 import cn.hutool.core.io.resource.ResourceUtil;
-import cn.hutool.core.util.NumberUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.*;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -11,6 +9,7 @@ import com.persagy.simulator.MeterSimulatorWalker;
 import com.persagy.util.ExcelSheet;
 import com.persagy.util.ExcelUtil;
 import com.persagy.util.FastJsonReaderUtil;
+import com.persagy.util.SslUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.dom4j.Document;
 import org.dom4j.Element;
@@ -153,15 +152,25 @@ public class Constant {
                     element = (Element) iter.next();
                     String[] serverURIs = new String[1];
                     serverURIs[0] = element.attribute("url").getValue();
-                    String clientId = element.attribute("clientId").getValue();
+                    String clientId = element.attribute("clientId").getValue()+"-"+ IdUtil.objectId();
                     String username = element.attribute("username").getValue();
                     String password = element.attribute("password").getValue();
                     String topic_prefix = element.attribute("topic_prefix").getValue();
+                    String caCrtFile = element.attributeValue("caCrtFile");
+                    String clientCrtFile = element.attributeValue("clientCrtFile");
+                    String clientKeyFile = element.attributeValue("clientKeyFile");
+                    String httpsHostnameVerificationEnabled = element.attributeValue("httpsHostnameVerificationEnabled");
                     mqtt_options.setServerURIs(serverURIs);
                     mqtt_options.setUserName(username);
                     mqtt_options.setPassword(password.toCharArray());
                     mqtt_clientId = clientId;
                     mqtt_topic_prefix = topic_prefix;
+                    log.warn("连接地址:{}",element.attributeValue("url"));
+                    if(serverURIs[0].contains("ssl") || serverURIs[0].contains("SSL")){
+                        log.warn("使用SSL认证");
+                        mqtt_options.setSocketFactory(SslUtils.getSocketFactory(caCrtFile,clientCrtFile,clientKeyFile,password));
+                        mqtt_options.setHttpsHostnameVerificationEnabled(BooleanUtil.toBoolean(httpsHostnameVerificationEnabled));
+                    }
                 }
 
             } else if (socket_or_mqtt.equals("socket")) {

+ 90 - 0
src/main/java/com/persagy/util/SslUtils.java

@@ -0,0 +1,90 @@
+package com.persagy.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMReader;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+
+/**
+ * @author lgy
+ * @date 2022/03/22 11:25
+ */
+@Slf4j
+public class SslUtils {
+    public static SSLSocketFactory getSocketFactory(final String caCrtFile, final String clientCrtFile, final String keyFile,
+                                                    final String password) throws Exception {
+        log.warn("caCrtFile:[{}],clientCrtFile:[{}],keyFile:[{}],password:[{}],",caCrtFile,clientCrtFile,keyFile,password);
+        Security.addProvider(new BouncyCastleProvider());
+        X509Certificate caCert = null;
+        X509Certificate cert = null;
+        KeyPair key = null;
+        if (caCrtFile != null) {
+            // 加载 CA 证书
+            log.info("加载CA证书 路径:{}",caCrtFile);
+            PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
+            caCert = (X509Certificate) reader.readObject();
+            reader.close();
+        }
+
+        if (clientCrtFile != null) {
+            // 加载 客户端 证书
+            log.info("加载客户端证书 路径:{}",clientCrtFile);
+
+            PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(clientCrtFile)))));
+            cert = (X509Certificate) reader.readObject();
+            reader.close();
+        }
+
+        if (keyFile != null) {
+            // 加载 客户端 私钥
+            log.info("加载客户端私钥 路径:{}",clientCrtFile);
+            PEMReader reader = new PEMReader(
+                    new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
+                    password::toCharArray);
+            key = (KeyPair) reader.readObject();
+            reader.close();
+        }
+
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        if (caCert != null) {
+            // CA证书用于对服务器进行认证
+            log.info("CA证书用于对服务器进行认证");
+            KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
+            caKs.load(null, null);
+            caKs.setCertificateEntry("ca-certificate", caCert);
+            tmf.init(caKs);
+        } else {
+            log.info("使用系统默认的安全证书");
+            //使用系统默认的安全证书
+            tmf.init((KeyStore) null);
+        }
+        KeyManagerFactory kmf = null;
+        if (key != null && cert != null) {
+            kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+            // 客户端密钥和证书被发送到服务器,以便服务器对我们进行身份验证
+            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+            ks.load(null, null);
+            ks.setCertificateEntry("certificate", cert);
+            ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
+            kmf.init(ks, password.toCharArray());
+        }
+        log.info("创建SSL套接字");
+        // 最后,创建SSL套接字,注意协议版本
+        SSLContext context = SSLContext.getInstance("SSL");
+        context.init(kmf == null ? null : kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+        return context.getSocketFactory();
+    }
+}
+