MQTT自签CA构建SSL加密消息通道服务
Publish: September 28, 2018 Category: 编程,代码分享,运维 6 Comments
SSL工作原理简介
需要知道的知识
- CA是什么?
CA证书授权中心(Certificate Center),也就是证书签发机构,比如Godaddy、WoSign,如果自己给自己签发证书,那我们自己就是CA,只不过别人不认可。他有两个重要属性,即:一、本身受信任,国际认可;二、给他受信任的申请对象签发证书。 - 什么是对称加密非对称加密,什么是公钥私钥?
通俗一点讲对称加密就是:用密钥加密明文得到的密文,使用该密钥解密得到明文。非对称加密:用密钥A加密明文得到的密文,使用密钥B解密得到明文,加密和解密的密钥不是同一个,我们称密钥A为私钥,密钥B为公钥。
因此要记住的一点常识:私钥用于加密,公钥用于解密。
- CA.key CA.crt Server.key Server.crt Client.key Client.crt等都是什么?
一般来说他们两个一组分别表示私钥和证书如下:
【CA.key CA.crt】
【Server.key Server.crt】
【Client.key Client.crt】
上面我们说了私钥和公钥的关系,那和证书的关系呢?证书简单来说就是带签名的身份信息。具体构成如下:
证书是如何签发的
服务器生成请求文件Server.csr,该文件内容主要是Server.key、组织信息、个人信息。提交给CA,CA审核之后签发给Server证书即Server.crt。该证书包括签名和明文信息两部分,其中签名使用ca.key即ca的私钥加密,到这里我们就能明白通过ca.pub也就是CA的公钥就能解密该签名信息,后面会提到为什么要解密该段签名。
单向SSL工作流程
(1) 申请证书:服务器生成请求文件Server.csr提交给CA
(2) 审核:CA审核服务器真实性
(3) 签发证书:证书内容就是上面提到的全部内容。到这里已经完成了整个SSL应用的部署,后面的步骤是具体的SSL工作流。
(4) TCP请求:当客户端要和服务器端通信,需要客户端发起一个TCP请求
(5) 返回证书:Server接收到Client的请求后会将证书Server.crt发送给Client。
(6) 验证证书:Client收到服务器证书Server.crt之后会对证书的签名解密,因此要用到对应的公钥,也就是CA的公钥,CA的公钥在CA证书里可以找到,CA证书是提前安装在客户端的。解密签名之后就可以校验摘要信息,域名信息等正确性
(7)协商通信密钥:如果证书校验通过,Server和Client将进行秘钥协商,然后Server和Client通信过程会采用对称秘钥加密。
- 单向认证和双向认证是什么?
大多情况下,尤其是web站点大多是单向认证即客户端只校验服务端真实性。双向认证在安全要求比较高的场景下需要双方都校验对方,两个过程极其类似,只是在Client认证完服务器证书后,Client会将自己的证书client.crt传给服务器,服务器验证通过后然后开始秘钥协商。
使用脚本自签证书
将 req_distingushed_name CN 192.168.10.253 和192.168.10.26 更改为自己的服务端和客户端IP或者域名,如果客户端不提供CN,直接将客户端的该项目删除即可。
#!/bin/bash
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the axTLS project nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# Generate the certificates and keys for testing.
#
PROJECT_NAME="TLS Project"
# Generate the openssl configuration files.
cat > ca_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME Dodgy Certificate Authority
EOF
cat > server_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME
CN = 192.168.10.253
EOF
cat > client_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME Device Certificate
CN = 192.168.10.26
EOF
mkdir ca
mkdir server
mkdir client
mkdir certDER
# private key generation
openssl genrsa -out ca.key 1024
openssl genrsa -out server.key 1024
openssl genrsa -out client.key 1024
# cert requests
openssl req -out ca.req -key ca.key -new \
-config ./ca_cert.conf
openssl req -out server.req -key server.key -new \
-config ./server_cert.conf
openssl req -out client.req -key client.key -new \
-config ./client_cert.conf
# generate the actual certs.
openssl x509 -req -in ca.req -out ca.crt \
-sha1 -days 5000 -signkey ca.key
openssl x509 -req -in server.req -out server.crt \
-sha1 -CAcreateserial -days 5000 \
-CA ca.crt -CAkey ca.key
openssl x509 -req -in client.req -out client.crt \
-sha1 -CAcreateserial -days 5000 \
-CA ca.crt -CAkey ca.key
openssl x509 -in ca.crt -outform DER -out ca.der
openssl x509 -in server.crt -outform DER -out server.der
openssl x509 -in client.crt -outform DER -out client.der
mv ca.crt ca.key ca/
mv server.crt server.key server/
mv client.crt client.key client/
mv ca.der server.der client.der certDER/
rm *.conf
rm *.req
rm *.srl
生成证书如下:
├── ca
│ ├── ca.crt
│ └── ca.key
├── ca.zip
├── certDER
│ ├── ca.der
│ ├── client.der
│ └── server.der
├── client
│ ├── client.crt
│ └── client.key
├── server
├── server.crt
└── server.key
EMQ配置用户名密码授权
进入emqttd安装目录,在etc/plugins下的emq_auth_username.conf。
配置相应的用户名密码
启用emq_auth_username插件:
./bin/emqttd_ctl plugins load emq_auth_username
EMQ配置单向SSL认证
listener.ssl.external.handshake_timeout = 15
listener.ssl.external.keyfile = etc/certs/server/server.key
listener.ssl.external.certfile = etc/certs/server/server.crt
EMQ配置双向SSL认证
## 开启双向认证
listener.ssl.external.cacertfile = etc/certs/ca/ca.crt
listener.ssl.external.verify = verify_peer
listener.ssl.external.fail_if_no_peer_cert = true
测试
Python写的基于Paho的双向认证测试脚本
# coding=utf8
import paho.mqtt.client as mqtt
from paho.mqtt.client import MQTT_LOG_DEBUG
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client = mqtt.Client()
client.on_connect = on_connect
# 项目目录
crtPath = '/home/evenvi/workspace/project_pri/deploy'
ca_certs = "%s/ca/ca.crt"%crtPath
certfile = "%s/client/client.crt"%crtPath
keyfile = "%s/client/client.key"%crtPath
client.tls_set(ca_certs=ca_certs,
certfile=certfile,
keyfile=keyfile
)
client.username_pw_set('admin', 'public')
client.connect('192.168.10.253', 8883)
client.loop_start()
msg = 'hello,world'
client.publish("tets/topic", msg, 0)
print("message published")
client.disconnect()
client.loop_stop()
print "done."
结语
MQTT是M2M的重要协议,其高效、简单、低成本的特点吸引了大批的开发者。同样MQTT的安全问题不容忽视,通过对SSL过程的梳理进一步加深对MQTT认识。
部分内容参考:
SSL/TLS 双向认证(二) -- 基于mosquittto的MQTT双向认证]
- [尚无相关文章]
怎么滴 要上https了?
甲方要求哈
博主写的很具体,参考博主的文章实现了mqtt自己签发证书,实现ssl加密功能。赞一个。
This solution is very good and helps me solve the basic problems, especially when dealing with MQTT's own issuance of SSL certificates, I don't know how to operate.
有个问题要请教下,那个emq好用还是mosquito好用,你们在生产环境里是如何选型的。另外ssl加密之后对速度有影响吗?
emq周边做的很全,mosquito简单方便,看自己项目需求做选型吧。
另外ssl对速度几乎没有影响