Emqtt的ssl/tls加密

继上个星期之后,这个星期有花了两三天的时间来搞emqtt的ssl/tls加密。

主流程还是参考了:https://blog.csdn.net/a704397849/article/details/88885198#commentsedit, 到最后一步用mosquitto_sub订阅消息的时候始终有问题:

联系了参考文章的作者,并且加了QQ,想不到是个很热情的人。他重新走了一下流程并且确定是没有问题的,给了我一份客户端的代码:

package com.zkong.mqttssl;

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class MqttTLSTest {

    static MqttClientCallback mqttClientCallback = new MqttClientCallback();
    static MqttAsyncClient mqttClient = null;

    static String username = "stan";  //注意这里 填你自己的mqtt账号密码
    static String password = "123456"; //注意这里 填你自己的mqtt账号密码
    //String broker = "tcp://xxx.xx.xxx.xxx:1883"; //注意这里要填自己mqtt服务器所在地址
    static String broker = "ssl://192.168.100.117:8883"; //注意这里要填自己mqtt服务器所在地址

    public static void main(String[] args) throws InterruptedException {
        start();
        while (true){
            Thread.sleep(10000);
        }
    }

    public static void start() {
        String clientId = "mqttserver" + String.valueOf(System.currentTimeMillis());

        try {
            mqttClient = new MqttAsyncClient(broker, clientId, new MemoryPersistence());
            mqttClient.setCallback(mqttClientCallback);

            //订阅 连接mqtt服务器
            subscribeConnect();

            //发布 连接mqtt服务器
            //... 略

        } catch (MqttException me) {
            System.out.println("reason " + me.getReasonCode());
            System.out.println("msg " + me.getMessage());
            System.out.println("loc " + me.getLocalizedMessage());
            System.out.println("cause " + me.getCause());
            System.out.println("excep " + me);
            me.printStackTrace();
        }
    }

    public static void subscribeConnect() {
        System.out.println("订阅连接");
        if (mqttClient != null) {
            try {
                MqttConnectOptions connOpts = new MqttConnectOptions();

                connOpts.setCleanSession(true);
                connOpts.setMaxInflight(100000);

                connOpts.setUserName(username);
                connOpts.setPassword(password.toCharArray());

                //ssl 连接 , 这里的 TrustManager 是自己实现的,没有去校验服务端的证书
                TrustManager[] trustAllCerts = new TrustManager[1];
                TrustManager tm = new MyTM();
                trustAllCerts[0] = tm;
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, null);
                SocketFactory factory = sc.getSocketFactory();
                connOpts.setSocketFactory(factory);
                //

                mqttClient.connect(connOpts, null, new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {
                        try {
                            //订阅 topic 为test 的消息,消息质量1
                            mqttClient.subscribe("test", 1);
                        } catch (MqttException me) {
                            System.out.println("reason " + me.getReasonCode());
                            System.out.println("msg " + me.getMessage());
                            System.out.println("loc " + me.getLocalizedMessage());
                            System.out.println("cause " + me.getCause());
                            System.out.println("excep " + me);
                            me.printStackTrace();
                        }
                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                        System.out.println("mqtt 没有连接上:" + exception.getMessage());
                        exception.printStackTrace();
                    }
                });
            } catch (MqttException me) {
                System.out.println("reason " + me.getReasonCode());
                System.out.println("msg " + me.getMessage());
                System.out.println("loc " + me.getLocalizedMessage());
                System.out.println("cause " + me.getCause());
                System.out.println("excep " + me);
                me.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
        }
    }

    //MyTM 是自己实现的认证管理类,里面并有校验服务端的证书就返回true,永久成功!
    static class MyTM implements TrustManager, X509TrustManager {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(X509Certificate[] certs) {
            return true;
        }

        @Override
        public void checkServerTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }
    }

    public static class MqttClientCallback implements MqttCallback{

        @Override
        public void connectionLost(Throwable arg0)
        {
            System.out.println("mqtt 失去了连接");
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0)
        {
            System.out.println("mqtt 发送完成!");
        }

        @Override
        public void messageArrived(String topic, MqttMessage message)
                throws Exception
        {
            String content = new String(message.getPayload(), "utf-8");
            System.out.println("收到mqtt消息,topic: "+topic+" ,content: "+content);
        }
    }
}

用这份客户端代码订阅消息,是没有问题的,因为我的服务器开启了基于mysql的认证,所以必须提供username和password。

要彻底走通的,估计还得找一台干净的机器重新安装emqtt。

有些问题在此记录一下:

关于mosquitto

它跟emqtt一样,本身也是一个mqtt的broker,在windows上安装完之后作为一个服务存在,当它处于启动状态时,会占掉1883端口导致emqtt无法完全启动,可以在Windows的服务管理中将其关闭:

Centos7上安装openssl

https://www.cnblogs.com/rxbook/p/9367725.html

Centos7上安装mosquitto

https://blog.csdn.net/xj178926426/article/details/78832296

 

未走通流程:

双向认证:https://blog.csdn.net/zljintan/article/details/83619309

自带证书验证(使用MQTTBox作为客户端):https://www.cnblogs.com/lexiaofei/p/8403995.html

 

 

 

 

转载于:https://my.oschina.net/u/4042451/blog/3103012

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Netty是一款高性能的网络应用框架,支持SSL/TLS加密来保护网络通信的安全性。SSL(Secure Sockets Layer)和TLS(Transport Layer Security)是网络通信中广泛使用的加密协议,用于在客户端和服务器之间建立安全的通信信道。 Netty提供了一些组件和类来实现SSL/TLS加密。首先,我们需要使用javax.net.ssl包中的类来创建SSLContext对象。SSLContext是SSL/TLS协议的入口点,它包含用于加密和解密数据的加密算法和密钥。我们需要为SSLContext对象配置密钥库和信任库,密钥库用于存储证书和私钥,而信任库用于存储可信的证书。 接下来,我们需要创建SslHandler对象,将其添加到Netty的ChannelPipeline中。SslHandler作为一个ChannelHandler,负责处理SSL/TLS握手过程和数据的加密解密。当建立连接时,SslHandler会自动执行握手过程,包括协商加密算法、验证证书以及生成会话密钥等。 一旦握手完成,SslHandler会将数据加密后发送到网络,并将接收到的密文解密成明文。这样可以确保在网络传输过程中的数据保密性和完整性。此外,SslHandler还提供了一些方法来获取会话信息,如远程主机的证书和协商的加密算法。 使用Netty的SSL/TLS加密功能能够有效地提高网络通信的安全性。通过配置SSLContext和添加SslHandler,我们可以方便地实现对网络通信的加密和解密。无论是在客户端还是服务器端,都可以使用Netty的SSL/TLS加密功能来保护数据的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值