砍材农夫砍材农夫
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • 环境配置
    • 微信生态
    • 正则
    • 全栈技能
  • java圈

    • java基础
    • jdk体系
    • jvm
    • spring框架
    • 分库分表
    • zookeeper
  • python技能

    • python编程
    • python数据
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • AIoT
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • devops
  • 元宇宙
  • 区块链
  • 物联网
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • 环境配置
    • 微信生态
    • 正则
    • 全栈技能
  • java圈

    • java基础
    • jdk体系
    • jvm
    • spring框架
    • 分库分表
    • zookeeper
  • python技能

    • python编程
    • python数据
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • AIoT
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • devops
  • 元宇宙
  • 区块链
  • 物联网
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 首页
    • 开发板介绍
    • micropython环境搭建
    • esp32开发板
    • 面包板
    • 万能表使用
  • 面包板
    • 点灯
  • esp32
    • 点亮开发板led灯
    • 点亮外接led
    • 点亮外接oled文字
    • 红外传感器
    • 红外传感器+olde
    • esp32+面包板
  • MQTT编程

    • MQTT入门

      • 物联网 MQTT
      • 物联网 MQTT和Socket
      • 物联网 MQTT订阅性能优势
      • 物联网 MQTT简易版Broker
    • HiveMQ

      • hivemq实战入门
    • Protobuf

      • Protobuf入门
      • Protobuf入门+梳理
      • Protobuf实战第一篇
    • emqx

      • emqx入门
    • mica

      • mica入门
    • netty

      • 入门

        • 基于netty构建入门
        • 理解粘包/拆包
        • 编解码器机制与自定义协议
        • 心跳和ack机制
        • mqtt服务demo演示
        • mqtt服务协议支持
        • mqtt服务udp支持
      • 协议规范

        • mqtt协议规范(发布/订阅模式)
        • mqtt协议规范(轻量级二进制协议)
        • mqtt协议规范(三种 QoS 等级)
        • mqtt协议规范(主题通配符订阅)
        • mqtt协议规范(遗嘱与保留消息)
      • 报文结构

        • 控制报文结构(报文分类)
        • 控制报文结构(连接与握手)
        • 控制报文结构(发布与接收)
      • 核心实战

        • 核心实战(握手与认证)
        • 核心实战(心跳保活机制)
        • 核心实战(会话管理)
        • 核心实战(安全)
    • mqtt-模拟器|客户端

      • 集成Paho

        • 设备模拟器设计
        • 设备模拟器演示
        • Paho拆解入门
        • Paho拆解核心
        • Paho拆解高性能
        • 其他客户端框架比较
      • NetAssist

        • 设备模拟器设计
      • hiveMq

        • hiveMq客户端
    • netty-mqtt-boot

      • 模块化设计
      • 统一接入层
      • 消息路由与流转层
      • 核心服务层
      • 业务应用层
      • 整体项目管理
      • 测试脚手架
      • 兼容支持
    • mqtt-压测

      • mqtt-jmeter

        • 模块化设计
      • ‌emqtt-bench

        • 模块化设计
    • mqtt-规则引擎

      • MQTT规则引擎
      • sql

        • 基于sql规则
      • ice

        • 模块化设计
      • Aviator

        • 模块化设计
      • Drools

        • 模块化设计
    • mqtt-实战问题

      • MQTT分布式集群

        • 分布式集群

          • 分布式集群意义
          • 如何构建分布式集群
          • 分布式集群简易版
          • mqtt入口HAProxy模拟负载
        • ignite

          • ignite入门
          • 模块化设计
      • 实战汇总

        • netty集成udp和tcp编码
        • mqtt集成tls
  • mqtt-netty源码拆解

    • mqtt-netty源码拆解

      • Pipeline双向链表
      • MqttEncoder.INSTANCE
      • 分布式集群简易版
      • mqtt入口HAProxy模拟负载
  • 物联网实战|spring-boot4 + hiveMQ|集成tls
    • 源码如下(mqtt-simulator-hivemq-01)
    • SAN是什么
    • 问题点
    • ca证书生成
      • window系统安装openssl
      • 将下面命名文件server.cnf,生成ca证书(包含subjectAltName-san)
      • 生成CA私钥(进入openssl目录bin下)
      • 生成CA证书
      • 生成结果
    • ca证书转换jks
      • 借助keytools(进入jdk目录bin下),将server.crt拷贝过来
    • spring-boot4 + hiveMQ集成
      • pom依赖
      • 代码如下
      • 结果如下
    • 如果ca缺失san证书,基于spring-boot4 下面错误

物联网实战|spring-boot4 + hiveMQ|集成tls

源码如下(mqtt-simulator-hivemq-01)

https://gitee.com/kcnf-iot/mqtt-simulator/tree/master/mqtt-simulator-hivemq-01

SAN是什么

  • Subject DN(主体名称)
旧标准里,证书域名写在 CN(Common Name,通用名)字段,只能填1 个域名
例:CN=shturl.cc/Y,只能匹配这一个网址
  • SAN(主题备用名称)
是 X.509 证书标准扩展字段,可以填写多个域名、IP、主机名,支持:
多个独立域名:a.com、b.com
泛域名:*.shturl.
IP 地址:192.168.1.1、IPv6
本地主机名、邮箱等

问题点

  • ca证书转换jks
  • spring-boot4开启san强校验问题

ca证书生成

window系统安装openssl

https://slproweb.com/products/Win32OpenSSL.html

将下面命名文件server.cnf,生成ca证书(包含subjectAltName-san)

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no

[req_distinguished_name]
CN = emqx.local

[v3_req]
keyUsage = keyEncipherment, dataEncipherment, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
IP.2 = 192.168.0.20

生成CA私钥(进入openssl目录bin下)

openssl genrsa -out server.key 2048

生成CA证书

openssl req -x509 -new -nodes -key server.key -sha256 -days 3650 -out server.crt -config server.cnf

生成结果

img

ca证书转换jks

借助keytools(进入jdk目录bin下),将server.crt拷贝过来

keytool -importcert -alias server -file server.crt -keystore truststore.jks -storepass 123456 -noprompt

img

spring-boot4 + hiveMQ集成

pom依赖

<dependencyManagement>
    <dependencies>
        <!-- Spring Boot Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>4.0.6</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<!-- HiveMQ MQTT5 客户端(同时兼容 MQTT3.1.1) -->
<dependency>
    <groupId>com.hivemq</groupId>
    <artifactId>hivemq-mqtt-client</artifactId>
    <version>1.3.15</version>
</dependency>

代码如下

package com.jysemel.iot;

import com.hivemq.client.mqtt.MqttClientSslConfig;
import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient;
import com.hivemq.client.mqtt.mqtt5.Mqtt5Client;
import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth;
import com.hivemq.client.mqtt.mqtt5.message.connect.Mqtt5Connect;

import javax.net.ssl.TrustManagerFactory;
import java.io.InputStream;
import java.security.KeyStore;
import java.util.UUID;

public class HiveMQTLSClientExample {

    private static final String MQTT_HOST = "192.168.0.20";
    private static final int MQTT_TLS_PORT = 8085;
    private static final String MQTT_USER = "test";
    private static final String MQTT_PWD = "123456";
    private static final int KEEP_ALIVE = 30;

    public static void main(String[] args)  {
        mqtt5AsyncClient();
    }

    public static Mqtt5AsyncClient mqtt5AsyncClient() {
        // 1. 加载CA根证书,构建SSL信任配置
        MqttClientSslConfig sslConfig = buildSslConfig();
        // 2. 构建MQTT TLS客户端
        String clientId = "server_" + UUID.randomUUID().toString().substring(0, 16);
        Mqtt5AsyncClient client = Mqtt5Client.builder()
                .identifier(clientId)
                .serverHost(MQTT_HOST)
                .serverPort(MQTT_TLS_PORT)
                .sslConfig(sslConfig)
                .buildAsync();
        // 3. 构建连接报文
        Mqtt5SimpleAuth simpleAuth = Mqtt5SimpleAuth.builder()
                .username(MQTT_USER)
                .password(MQTT_PWD.getBytes())
                .build();
        Mqtt5Connect connectMsg = Mqtt5Connect.builder()
                .cleanStart(true)
                .simpleAuth(simpleAuth)
                .keepAlive(KEEP_ALIVE)
                .build();
        // 4. 发起异步连接
        client.connect(connectMsg)
                .whenComplete((connAck, throwable) -> {
                    if (throwable != null) {
                        throwable.printStackTrace();
                        System.out.println("MQTT TLS连接失败 ");
                        return;
                    }
                    System.out.println("MQTT TLS连接成功,clientId ");
                });
        return client;
    }

    private static MqttClientSslConfig buildSslConfig() {
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            try (InputStream is = HiveMQTLSClientExample.class.getResourceAsStream("/cert/emqx.jks")) {
                if (is == null) {
                    throw new RuntimeException("信任库文件未找到: /cert/emqx.jks");
                }
                String trustStorePassword = "123456";
                trustStore.load(is, trustStorePassword.toCharArray());
            }

            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(trustStore);

            return MqttClientSslConfig.builder()
                    .trustManagerFactory(tmf)
                    // 关键:自定义 HostnameVerifier,总是验证通过(仅测试用!)
                    .hostnameVerifier((hostname, session) -> true)
                    .build();
        } catch (Exception e) {
            throw new RuntimeException("SSL 初始化失败", e);
        }
    }
}

结果如下

img

如果ca缺失san证书,基于spring-boot4 下面错误

avax.net.ssl.SSLHandshakeException: No subject alternative names present
com.hivemq.client.mqtt.exceptions.ConnectionFailedException: javax.net.ssl.SSLHandshakeException: No subject alternative names present
Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative names present
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:383)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:326)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1287)
最近更新: 2026/7/7 20:34
Contributors: kcnf
Prev
netty集成udp和tcp编码