SSL-TLS 双向认证(三) -- ESP8266与mosquitto的MQTT双向认证

本文部分参考:
https://github.com/tuanpmt/esp_mqtt
http://espressif.com/zh-hans/products/hardware/esp8266ex/overview

前言

ESP8266是一颗低功耗、高集成度、性能稳定的 Wi-Fi 芯片,是物联网开发的首选设备。ESP8266EX 专为移动设备、可穿戴电子产品和物联网应用而设计,通过多项专有技术实现了最低功耗。ESP8266EX 有三种运行模式:激活模式、睡眠模式和深度睡眠模式,能够延长电池寿命。 ESP8266EX 是业内集成度最高的 Wi-Fi 芯片,最小封装尺寸仅为 5mm x 5mm。ESP8266EX 高度集成了天线开关、射频 balun、功率放大器、低噪放大器、过滤器和电源管理模块,仅需很少的外围电路,可将所占 PCB 空间降到最低。ESP8266EX 集成了更多的元器件,性能稳定,易于制造,工作温度范围达到 -40°C 到 +125°C。
mosquitto是一款精致的MQTT broker.一款实现了消息推送协议 MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,比如现在应用广泛的低功耗传感器,手机、嵌入式计算机、微型控制器等移动设备。
mosquitto的相关使用请参考上一篇博客: http://blog.csdn.net/ustccw/article/details/76905459#t8

一: 目的

使用mosquitto broker 作为 MQTT server,开启双向认证。同时 mosquitto broker 订阅主题 /mqtt/topic/1 ,使用 ESP8266 作为 MQTT Client,开启双向认证,订阅和发布主题 /mqtt/topic/1。如果 mosquitto broker 收到ESP8266 的消息,则成功实现ESP8266与mosquitto的MQTT双向认证。

二: ESP8266及开发环境搭建

如果您熟悉ESP8266开发环境,可以很顺利理解下面步骤; 如果您不熟悉某个部分,比如编译,烧录。需要您结合官方的相关文档来理解。http://espressif.com/zh-hans/support/download/overview,如您需阅读ESP8266 快速入门指南文档。

1.1 ESP8266NONOS SDK和MQTT Demo获取

$git clone https://github.com/ustccw/MQTTESP8266.git
  • 1

可获取ESP8266开发SDK,此SDK可以保证ESP8266良好工作。如图,esp_mqtt_proj 目录是MQTT Demo.

esp8266

1.2 编译器获取

https://github.com/ustccw/RepoForShareData/tree/master/ESP/ESP8266/compiler,xtensa-lx106-elf.tar.bz2是编译器压缩包,解压后 xtensa-lx106-elf 是编译器根目录,将编译器拷贝至 /opt/ 下。

1.3 mqtt demo 修改

esp_mqtt_proj/include/mqtt_config.h 需修改的地方

        1. #define CFG_HOLDER   0x00FF55A4      // 编译前,改变这个数值。如将 0x00FF55A4 改为 0x00FF55A5。下次编译,不用再改,这个参数将保证设备自动配网,如会保存WiFi账号密码等。
        2. #define MQTT_SSL_ENABLE              // 不可注释,单向认证和双向认证必选
        2. #define MQTT_HOST "192.168.111.100"  // 修改为 MQTT 服务器的IP或域名
        3. #define MQTT_PORT    8883                // 修改为 MQTT 服务器开放的端口号
        4. #define MQTT_CLIENT_ID   "chenwucontrol" // 可选,这是向服务器注册自己的ID
        5. #define MQTT_USER            "chenwu"    // 可选,向服务器注册自己的用户名。注意:服务器必须是允许匿名登录。否则必须配置有效的用户名
        6. #define MQTT_PASS            "chenwu"    // 可选,向服务器注册用户名对应的密码,同上
        7. #define STA_SSID "BL_841R"               // 配置设备联网,AP 的 SSID
        8. #define STA_PASS "1234567890"            // 配置设备联网,AP 的 密码
        9. #define DEFAULT_SECURITY 1               // 必须配置为 1,表示启用 SSL 认证,如果配置为 0 ,则关闭 SSL 认证。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

注意:
关于ESP8266的SSL/TLS相关问题,需结合ESP8266 NONOS SDK SSL 加密用户手册理解。

下面主要说一下demo中三个重要接口:

espconn_secure_ca_enable(0x01,0x77);
  • 1

此接口使能CA,这样 ESP8266 作为 SSL client,需校验服务器的证书。
参数 0x01 表示 ESP8266 作为 SSL Client。
参数 0x77 表示 CA 证书位置 0x77000,需和1.7节中烧录的位置对应!// 用户自定义位置

espconn_secure_cert_req_enable(0x01,0x78);
  • 1

此接口使能client,这样 ESP8266 作为SSL client,将把自己的证书传给SSL server,让服务器校验。双向认证不可注释!单向认证需注释。
参数 0x01 表示 ESP8266 作为 SSL Client。
参数 0x78 表示 ESP8266 client 端证书位置 0x78000,需和1.7节中烧录的位置对应!// 用户自定义位置

如果烧录的CA bin大于4K,则接口使用和烧写client证书需在0x78000以后的位置,避免覆盖CA证书。

espconn_secure_set_size(ESPCONN_CLIENT,6*1024);
  • 1

设置证书缓存大小,如果服务器证书为4KB, 那么第二个参数至少要保证4KB大小。参数不宜过大,否则应用层内存将很小。参数太小,可能会引起握手失败。

1.4 mqtt demo 编译

导出编译器环境变量:

$export</span> PATH<span class="hljs-subst">=</span>/opt/xtensa<span class="hljs-attribute">-lx106</span><span class="hljs-attribute">-elf</span>/bin<span class="hljs-subst">/</span>:<span class="hljs-variable">$PATH
  • 1

导出SDK环境变量:

$export SDK_PATH=~/MQTTESP8266/
$export BIN_PATH=~/MQTTESP8266/bin
  • 1
  • 2

编译: 编译选项依次选择 1 1 2 0 5

$./gen_misc.sh
  • 1

compile

编译成功如下:
success

编译成功的bin文件位于bin/upgrade/user1.2048.new.5.bin

1.5 mqtt demo 及参数烧录

烧写工具 esptool.py 可从官网获取 https://github.com/espressif/esp-idf/tree/master/components/esptool_py
建议git clone https://github.com/espressif/esp-idf.git 来获取整个 esptool.py 套件。
将ESP8266调到烧写模式进行以下烧写:
擦除整块 flash:

$~/esp/esp-idf/components/esptool_py/esptool/esptool.py --port /dev/ttyUSB0 --baud 921600 erase_flash
  • 1

烧写user bin及相关参数:

$~/esp/esp-idf/components/esptool_py/esptool/esptool.py --port /dev/ttyUSB0 --baud 921600 write_flash 0x00000 ~/MQTTESP8266/bin/boot_v1.6.bin 0x1000 ../bin/upgrade/user1.2048.new.5.bin 0x1fe000 ~/MQTTESP8266/bin/blank.bin 0x1fc000 ~/MQTTESP8266/bin/esp_init_data_default.bin
  • 1

flashwrite

1.6 证书制作

根据您的情况,选择 a,b,c 中一个进行。
a) 如果您没有任何证书

我们提供了如图工具:

tools

makefile.sh

$./makefile.sh
  • 1

生成所有相关证书文件。
rmfile.sh

$./rmfile.sh
  • 1

删除产生过的所有文件。

gen_appbin.py // 和证书生成无关,编译过程需要的工具
make_cacert.py // 参与CA证书的制作和格式转化
make_cert.py // 参与client证书制作和格式转化

crt

b) 如果您有正式CA证书ca.crt,以及该CA颁发的客户端证书client.crt和私钥client.key

  • 如果不是此名称,请重命名文件!
  • 确保证书是pem格式
  • 拷贝ca.crt 、client.crt、 client.key至tools目录下

trustca

makefile.sh: 证书处理和格式转化,必须进行此操作
rmfile.sh: 删除产生过的文件

$./makefile.sh
  • 1

gen1

c) 如果您只有正式CA证书ca.crt,没有客户端证书

同上操作,只能生成ca相关文件,并只能完成单向认证

justca

makefile.sh生成CA相关文件

$./makefile.sh
  • 1

p1

1.7 证书烧录

需烧录的证书位于 /tools/bin 目录下

esp_ca_cert.bin // CA的证书
esp_cert_private_key.bin // 客户端证书和私钥

烧录方法:

$~/esp/esp-idf/components/esptool_py/esptool/esptool.py --port /dev/ttyUSB0 --baud 921600 write_flash  0x77000 ~/MQTTESP8266/tools/bin/esp_ca_cert.bin
$~/esp/esp-idf/components/esptool_py/esptool/esptool.py --port /dev/ttyUSB0 --baud 921600 write_flash  0x78000 ~/MQTTESP8266/tools/bin/esp_cert_private_key.bin
  • 1
  • 2

caflash

注意:
[重要] 烧录位置需和1.3节中espconn_secure_ca_enable,espconn_secure_cert_req_enable 参数位置对应。

1.8 MQTT broker配置

参考上一篇博客http://blog.csdn.net/ustccw/article/details/76905459
mosquitto的相关使用请参考上一篇博客: http://blog.csdn.net/ustccw/article/details/76905459#t8

设置broker的端口,开启双向认证。

mosconfig

1.9 MQTT broker启动

mosquitto的相关使用请参考上一篇博客: http://blog.csdn.net/ustccw/article/details/76905459#t8

$mosquitto -c /etc/mosquitto/mosquitto.conf -v
  • 1

broker1

1.10 MQTT subscribe client启动

mosquitto的相关使用请参考上一篇博客: http://blog.csdn.net/ustccw/article/details/76905459#t8

$mosquitto_sub -h 192.168.111.100 -p 8883 -t "/mqtt/topic/1" --cafile /home/chenwu/MQTTESP8266/tools/ca/ca.crt --cert /home/chenwu/MQTTESP8266/tools/client/client.crt --key /home/chenwu/MQTTESP8266/tools/client/client.key
  • 1

sub1

1.11 MQTT publish client-ESP8266启动

将ESP8266调至运行模式,串口查看log

$ miniterm.py /dev/ttyUSB0 115200
  • 1

esp1

三: 结果展示

3.1 MQTT broker端

b1

New client connected from 192.168.111.100 as mosqsub… // MQTT Broker收到订阅端连接
New client connected from 192.168.111.101 as chenwucontrol… // MQTT Broker收到ESP8266连接
Received PUBLISH from chenwucontrol.. // MQTT Broker收到 ESP8266 的发布消息
Sending PUBLISH to chenwucontrol… // MQTT Broker 将消息广播到订阅段
Sending PINGRESP to mosqsub… // 发送心跳包
Received PINGRESP to mosqsub… // 收到心跳包

3.2 MQTT subscribe client端

h1

订阅段收到来自 ESP8266 发布的消息: hello1

3.3 MQTT publish client - ESP8266端

esp8266

四: 故障排除

4.1 为什么找不到编译器/编译器组件缺失?

重新下载编译器,http://blog.csdn.net/ustccw/article/details/76977004#t4
导入编译器环境变量,环境变量生存周期和shell生存周期相同。一旦shell关闭,需重新导入。

$export</span> PATH<span class="hljs-subst">=</span>/opt/xtensa<span class="hljs-attribute">-lx106</span><span class="hljs-attribute">-elf</span>/bin<span class="hljs-subst">/</span>:<span class="hljs-variable">$PATH
  • 1

4.2 为什么编译失败?
a) 根据1.4节重新导入SDK等环境变量
b) 确保你当前位于 MQTTESP8266/esp_mqtt_proj 目录下

4.3 为什么烧写失败?
a) 确保你从 https://github.com/espressif/esp-idf.git 获取到完整的烧写工具 esptool.py
记得使用

$git submodule init
$git submodule update
  • 1
  • 2

来获取子模块。
b) 确保端口正确,波特率设置正确,烧写位置正确

4.4 为什么启动mqtt subscribe 订阅段失败?
a) 重新确定你MQTT broker 的IP地址和端口
b) 重新确认你 CA 证书位置,client 证书和私钥位置是否正确

4.5 为什么串口查看是乱码?
a) 波特率是否设置为 115200
b) blank.bin, boot_v1.6.bin, esp_init_data_default.bin, user1.2048.new.5.bin是否都烧录到正确位置。

4.6 为什么ESP8266联网失败?
#define CFG_HOLDER
#define STA_SSID
#define STA_PASS
是否修改?

4.6 为什么SSL/TLS握手失败?
a) 仔细阅读1.6节 ,重新尝试生成证书,可能是生成的证书不匹配。如: 没有使用makefile.sh来生成对应证书
b) 服务器和ESP8266单向认证,双向认证不匹配。如: 服务器开启双向认证,ESP8266没有烧写自己的 esp_cert_private_key.bin ,或没有调用 espconn_secure_cert_req_enable(0x01,0x78);
c) 证书烧入位置和软件中读取位置不匹配。如 CA烧录位置为0x77000,软件中却使用0x78.(将从0x78000读取CA证书)
d) 证书烧录有覆盖。如:CA证书大小大于两个证书烧录位置之差的大小。则需合理分配烧录位置
e) 尝试修改 espconn_secure_set_size(0x01,6*1024)和 ESPCONN_SECURE_MAX_SIZE 来分配握手内存。这个情况居多,一般增大ESPCONN_SECURE_MAX_SIZE,修改6*1024这个值。
f) 确保你使用的是 libssl.a. 在Makefile中76行应该是 -lssl 而不是 -lmbedtls
g) 服务器 mosquitto.conf 证书等路径需设置为绝对路径
h) 确保 SNTP 获取到正确时间,如果没有,重启芯片

4.7 为什么收不到ESP8266的MQTT消息?
a) 订阅的主题不匹配
b) 连接服务器设置的参数不正确,参考1.3节重新设置

        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>
阅读更多
个人分类: espressif
上一篇SSL-TLS 双向认证(二) -- 基于mosquittto的MQTT双向认证
下一篇wifi一键配网smartconfig原理及应用
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭