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.
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
编译成功如下:
编译成功的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
1.6 证书制作
根据您的情况,选择 a,b,c 中一个进行。
a) 如果您没有任何证书
我们提供了如图工具:
makefile.sh
$./makefile.sh- 1
生成所有相关证书文件。
rmfile.sh
$./rmfile.sh- 1
删除产生过的所有文件。
gen_appbin.py // 和证书生成无关,编译过程需要的工具
make_cacert.py // 参与CA证书的制作和格式转化
make_cert.py // 参与client证书制作和格式转化
b) 如果您有正式CA证书ca.crt,以及该CA颁发的客户端证书client.crt和私钥client.key
- 如果不是此名称,请重命名文件!
- 确保证书是pem格式
- 拷贝ca.crt 、client.crt、 client.key至tools目录下
makefile.sh: 证书处理和格式转化,必须进行此操作
rmfile.sh: 删除产生过的文件
$./makefile.sh- 1
c) 如果您只有正式CA证书ca.crt,没有客户端证书
同上操作,只能生成ca相关文件,并只能完成单向认证。
makefile.sh生成CA相关文件
$./makefile.sh- 1
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
注意:
[重要] 烧录位置需和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的端口,开启双向认证。
1.9 MQTT broker启动
mosquitto的相关使用请参考上一篇博客: http://blog.csdn.net/ustccw/article/details/76905459#t8
$mosquitto -c /etc/mosquitto/mosquitto.conf -v- 1
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
1.11 MQTT publish client-ESP8266启动
将ESP8266调至运行模式,串口查看log
$ miniterm.py /dev/ttyUSB0 115200- 1
三: 结果展示
3.1 MQTT broker端
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端
订阅段收到来自 ESP8266 发布的消息: hello1
3.3 MQTT publish client - 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>
智能推荐
https双向认证试验
双向校验流程见: https://www.cnblogs.com/baihuitestsoftware/articles/7097389.html 1.利用xca工具生成CA,client,server端证书 创建CA证书: 1) 使用模板创建新证书CA ,点击 应用模板所有信息。 2)主体里填写国家等信息,commonName随便填一个ca名称。 3)创建一个ca的**。 &...
https双向认证
一、概念 根证书:是生成服务器证书和客户端证书的基础,是信任的源头,也可以叫自签发证书,即CA证书。 服务器证书:由根证书签发,并发送给客户,让客户安装在浏览器里的证书。主要包含服务端的公钥、域名和公司信息,浏览器客户端会验证自己请求的地址是否和证书里面的地址是否相同。 客户端证书:由根证书签发,需要导入到服务器的信任库中。主要包含客户端公钥、域名和公司信息。 二、目标 1、单向验证:如果是你客户...
ssl双向认证和单向认证原理
有朋友在搞一个项目,周末有聊到一些安全性的东西,很自然会想起https,但https究竟如何实施,其原理又是什么? 基于ssl,一般的应用都是单向认证,如果应用场景要求对客户来源做验证也可以实现成双向认证。 网上google一下: 为了便于更好的认识和理解 ...
HTTPS单向认证和双向认证
Android客户端开发中,经常用到http或https做网络请求。 二者的区别如下: 1、http是超文本传输协议,信息是明文传输,对于网络访问不安全; 而https则是具有安全性的ssl加密传输协议。 2、http和https使用的端口也不一样,前者是80,后者是443。 3、二者用的是完全不同的连接方式:http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密...
kubernetes https双向认证-----ca认证
为什么写这个呢? 在没有了解k8s认证的时候干过一件蠢事,公司项目是通过bearer token进行权限认证的,当时一直在纠结这个token是哪儿来的,然后各种查询secret对比是否一样,最后找到了一个,那个时候并不知道这个token是如何认证的,如何拥有资源的操作权限的,就跑到一个qq群里面去问了一个问题, 感觉自己跟个傻子一样。 这个问题当时并没有去深究,后面不知道干什么事把这个给忘了,前几...
猜你喜欢
NGINX 配置 SSL 双向认证
以前总觉得配置nginx这种问题看看网上教程就行了自己配置的时候才发现有些问题真的不是看一篇两篇教程就能搞定的 所以自己写一个备忘的配置流程 说不定什么时候就用上了。 对于 nginx 的 HTTPS 配置,通常情况下我们只需要实现服务端认证就行,因为浏览器内置了一些受信任的证书颁发机构(CA),服务器端只需要拿到这些机构颁发的证书并配置好,浏览器会自己校验证...
第三方库PNChart的使用
PNChart 是一个强大的带动画的图表库 要是用这个库可以使用pods,也可以直接将库导入项目中,必须引入"PNChart.h"头文件 下面我们来看一下代码! 转载于:https://www.cnblogs.com/aeronfay/articles/4929223.html...
LeetCode刷题笔记(10)-BFS广度优先搜索
LeetCode刷题笔记(10)-BFS广度优先搜索 127、单词接龙 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则: 每次转换只能改变一个字母。 转换过程中的中间单词必须是字典中的单词。 输入: beginWord = “hit”, endWord = &ldqu...
线性筛选素数的方法及基于线性筛选素数的欧拉函数筛选莫比乌斯函数筛选
欧拉筛法线性求素数 回忆一下经典的埃式筛法求素数。时间复杂度是为O(nloglogn)(我之前一直以为是O(n))O(nloglogn)(我之前一直以为是O(n)) 显然,当一个数是素数的时候,那么他的倍数肯定是合数,筛选标记即可 我们来举个列子 筛选2-10的素数 首先2是素数,然后把其倍数删去,我们标记下删去的次数用一个斜杠表示删去了一次 之后3是素数,继续删去倍数,这个时候发现6被重复删去两...
JEECG 页面多个用户选择器只显示最后一个
在一个页面当中,我们可能会需要有多个的用户选择器进行快速的录入,此时会发现所有的输入都会在最后一个用户选择器的地方显示 查看页面代码当中的ID也是不一致: 查看通过标签生成之后的源码,可以发现所有的用户选择器都会生成一个 点击输入框调用的js方法都是一样的,看到这里也就可以明白为什么都是只有最后一个用户选择输入框当中有数据了。 因此我们对后台当中标签代码生成部分进行改造,让其支持多个用户选择器: ...
