esp8266物联网开发五:SSL保驾护航

摘要:
当前https传输的底层使用SSL/TLS协议加密。然后尝试向/test/say管道发送消息。您可以看到订阅者已收到消息。发布者接口如下:订阅者接口如下:在双向身份验证过程中配置服务器端的授权过程后,我们成功使用客户端通过SSL连接到服务器并控制消息。

说在前面

数据在网络上传输,如果是明文传输,肯定是不安全的,所以得将数据进行加密。现在主流的加密方式,就是利用SSL/TLS协议加密,其实SSL和TLS可以看做是一个协议,它运行在传输层和应用层之间的一层协议,通过将TCP/UDP传输的数据加密之后,再传送到另一端。这样数据就安全了。

现在的https传输,底层就是利用了SSL/TLS协议进行了加密。当然,Mail,FTP等其他基于TCP/UDP传输协议之上构建的应用程序,也都是可以使用这种加密协议的。那么MQTT在数据传输中,是否也可以进行传输加密呢?答案是肯定的,因为MQTT也是基于TCP协议之上实现的,所以想要实现起来,并不难。

在开始进行MQTT数据传输加密的实操之前,我们先来储备点SSL/TLS协议的知识,以便于更好的进行理解。

说道SSL/TLS协议,其诞生可以追溯到前浏览器霸主NetScape,为了解决数据传输安全问题而发明了SSL协议,先是产生了SSL1.0,然后产生了SSL2.0,之后是SSL3.0,由于协议成熟且使用量大,后来被IETF对SSL3.0进行了标准化并添加了少量其他机制,更名成了TLS1.0。更多的细节,可以百度“RFC2246-TLS加密协议详解”,也可以去www.rfc-editor.org网站,通过搜索RFC2246来了解更多细节。

OPENSSL,是对SSL/TLS协议进行实现的开源软件,其中包含了加解密所用到的各种算法,算是密码学这块的集大成者。

今天我们要用它来通过特定的流程来生产出我们需要的加密机制,从而使得MQTT的传输更安全。

握手流程

首先来说明一下SSL/TLS协议的经典握手流程,只有通过此流程,后续的数据传输才能正常的进行加密并传输。整体流程如下:

image

由于上图描述都是英文,理解起来比较困难,我就拿阮一峰的描述来进行,Vistor我们称为Alice,CloudFlare我们称为Bob,描述如下:

第一步,爱丽丝给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。

第二步,鲍勃确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。

第三步,爱丽丝确认数字证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给鲍勃。

第四步,鲍勃使用自己的私钥,获取爱丽丝发来的随机数(即Premaster secret)。

第五步,爱丽丝和鲍勃根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程。

可以看到整体流程比较复杂,而且涉及到了加密方法,数字证书,公钥,私钥等名词,我大概做一下解释。

加密方法:数据传输加密,可以用多种方法,图例中选用的是RSA,即非对称加密算法。

公钥:公开的密匙文件,任何用户都可以自由访问,通常以.pem结尾

私钥:非公开的密匙文件,通常由加密方自己保管,必须得保证其私密性,通常以.key结尾

数字证书:包含数字签名和公钥的证书,客户端可以通过CA来验证数字签名,通常以.cer, .crt结尾

大致知道这些名词的意思后,接下来我们通过更加具体的流程讲解,来逐渐清晰化。

授权流程

CA中心的授权流程

image

由于CA证书要进行证书授权,所以必须先创建一个自己的私钥,然后通过此私钥生成自己的自签证书。由于这里我们无法真正的CA中心来模拟,因为是收费的,好在openssl为我们提供了自建CA中心的选项,使得可以使用如下的命令来模拟。

1.创建私钥,执行命令:

openssl genrsa -out D:/sslkey/ca/MyRootCA.key 2048 

可以看到在文件夹中生成了私钥

2.生成自签证书,执行命令:

openssl req -x509 -new -nodes -key D:/sslkey/ca/MyRootCA.key -sha256 -days 3650 -subj "/CN=www.scy.com" -out D:/sslkey/ca/MyRootCA.pem

填写好相关信息后,最终在文件夹中生成了自签证书。需要说明的是,由于是模拟的CA中心,所以这里稍显繁琐,如果使用的是外部CA中心,则无需关心这些问题。同时,如果用户想自定义自己的信息,请把-subj配置去掉即可,后面的请求也类似。

CA证书整体的准备工作到此。

Server端的授权流程

image

Server端的授权流程也比较简单,首先是创建server端使用的私钥,然后通过此私钥创建证书请求,请求会被推送到CA中心进行处理,处理完毕后,会将证书颁发给Server端。

1.创建私钥,执行命令:

openssl genrsa -out D:/sslkey/server/MyEMQ1.key 2048 

2.创建证书请求,执行命令:

openssl req -new -key D:/sslkey/server/MyEMQ1.key -out D:/sslkey/server/MyEMQ1.csr -subj "/CN=127.0.0.1"

3.CA中心颁发证书,执行命令:

openssl x509 -req -in D:/sslkey/server/MyEMQ1.csr -CA D:/sslkey/ca/MyRootCA.pem -CAkey D:/sslkey/ca/MyRootCA.key -CAcreateserial -out D:/sslkey/server/MyEMQ1.pem -days 3650 -sha256

执行这三步完毕之后,整体流程完毕,我们接下来将这些文件配置到EMQ的配置文件中来启动SSL。

打开etc目录中的emqx.conf文件,修改选项为以下三个配置(需要提前将授权文件拷贝到certs目录):

#ssl port:
listener.ssl.external = 8883
#private key for emq cert:
listener.ssl.external.keyfile = etc/certs/MyEMQ1.key
#emq cert:
listener.ssl.external.certfile = etc/certs/MyEMQ1.pem
#CA cert:
listener.ssl.external.cacertfile = etc/certs/MyRootCA.pem
后,重启EMQX服务器即可。
 

这样,此根证书生成完毕,然后就能为后续进来的请求进行授权操作。

接下来打开MQTTX客户端程序,建立SSL链接来试试是否可以正常操作:

image

配置好之后,点击连接按钮,进行连接,可以看到已经连接到服务器且在在ssl端口8883进行监听了。

image

然后尝试向/test/say管道发送消息,可以看到订阅者已经能接收到了:

发布者界面如下:

image

订阅者界面如下:

image

双向认证流程

上面配置好Server端的授权流程后,我们成功的使用客户端通过SSL连接上了服务端并进行了消息操控。但是上面只是单向认证流程,因为Client端并未做认证操作。这里我们将来说下怎么进行双向认证流程。

Server端的授权流程,我就不用说了,上面有讲解到。按照流程操作即可。

Client端的授权流程,其实和Server端的授权流程一模一样,我们来依葫芦画瓢一下,进入C:Program FilesOpenSSL-Win64in目录,执行下面的命令。

1.创建私钥,执行命令:

openssl genrsa -out D:/sslkey/client/MyClient1.key 2048 

2.创建证书请求,执行命令:

openssl req -new -key D:/sslkey/client/MyClient1.key -out D:/sslkey/client/MyClient1.csr -subj "/CN=127.0.0.1"

3.CA中心颁发证书,执行命令:

openssl x509 -req -in D:/sslkey/client/MyClient1.csr -CA D:/sslkey/ca/MyRootCA.pem -CAkey D:/sslkey/ca/MyRootCA.key -CAcreateserial -out D:/sslkey/client/MyClient1.pem -days 3650 -sha256

全部执行完毕,则Client端的授权流程完毕,结果如下:

image

文件生成如下:

image

之后,我们需要配置一下,以便于启动EMQ的客户端SSL认证,同样的打开etc目录中的emqx.conf文件,修改如下配置:

#enable the client side certificates
listener.ssl.external.verify = verify_peer
#set it to 'true' to allow the ssl with client side certificate only 
listener.ssl.external.fail_if_no_peer_cert = true

然后重新启动EMQX即可。

 esp8266物联网开发五:SSL保驾护航第10张

 上图为配置方式,配置完毕之后,点击连接按钮,就可以连接到Server了。之后模拟信息收发:

esp8266物联网开发五:SSL保驾护航第11张

题外话

单向认证和双向认证,少了一个认证步骤,一般在物联网Client设备较多的情况下,使用单向认证则可以获得更好的性能。如果数据非常重要且不会有性能问题的时候,使用双向设备则更合适。

考虑到CA颁发的证书都有时效性,物联网设备特别多的情况下,这种情况显得尤为明显,所以针对自己的设备规模,选择合适的认证,也是非常重要的。

本节就到这里,希望能抛砖引玉。

参考资料:

Securing EMQ Connections with SSL

图解ssl

免责声明:文章转载自《esp8266物联网开发五:SSL保驾护航》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java异常错误重试方案研究(转)(spring-retry/guava-retryer)mybatis的xml中sql语句中in的写法(迭代遍历)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于 移动端实现 点击按钮复制指定内容到剪切板 的坑

最近项目中遇到一个需求 : html5页面 点击立即邀请出现分享弹窗 然后点击复制链接区域复制 自定义链接(拼接网站注册链接 + 邀请码) 到剪切板 如图: 在网上搜到   clipboard.js 可实现需求 。 clipboard.js  GitHub:https://github.com/zenorocha/clipboard.js 网址:http...

在Eclipse下搭建Android开发环境教程,HelloWord

本文将全程演示Android开发环境的搭建过程,无需配置环境变量。所有软件都是写该文章时最新版本,希望大家喜欢。 我们昨天向各位介绍了《在NetBeans上搭建Android SDK环境》,前不久也介绍过《在MyEclipse 8.6上搭建Android开发环境》,都受到了读者的欢迎。但是很多朋友都认为NetBeans在中国用户不多,MyEcli...

Flask入门学习——蓝图Blueprint

flask蓝图可以实现应用程序的模块化,即通常作用于相同的url前缀,eg:/user/id,/user/profile等类似这样,可以放在一个模块当中,这样会让应用更加清晰便于开发与维护。 这里有个例子:(来源:Python web开发实战-董伟明) 模块user.py: from flask import Blueprint bp = Bluepri...

【转】越狱的 iPhone、iPad 通过网站实现一键安装 ipa 格式的 APP 应用

1、已经越狱的 iPhone、iPad 设备,当通过其自带的 safari 浏览器访问 ipa 应用下载网站时,利用 itms-services 协议,可以一键安装 ipa 文件的 iOS 应用,例如: <a href="http://t.zoukankan.com/itms-services://?action=download-manifest&...

macOS应用程序如果在打开时提示崩溃,该怎么解决

macOS应用程序如果在打开时提示崩溃,该怎么解决?最近一次Apple静默更新之后,Apple删除了TNT的证书,因此应用程序将在7月12日之后崩溃。目前的解决方案是自己签名。 检测软件签名是否存在 1.打开终端,输入【sudo -s】2.然后会提示你输入开机密码,你就把密码输入***,输入过程中不会显示密码,输入完成后按确认键enter3.然后再终端输入...

.deb文件打包

最近因项目需要,需要把文件夹打包为.deb格式的包,幸亏一位朋友帮忙指导了我一个晚上,才得以完成,这里再次对他表示感谢。 整理打包流程如下: 请先参考此博客内容,了解deb文件打包 如何制作Deb包和相应的软件仓库,其实这个很简单。这里推荐使用dpkg来进行deb包的创建、编辑和制作。 首先了解一下deb包的文件结构: deb 软件包里面的结构:它具有D...