基于SSL/TLS双向安全连接设备CA证书认证

小伙伴儿们,如果觉得文章干货满满,欢迎加入公众号【编程识堂】,更多干货等你们来哦!

背景消息

  • 设备证书是由CA根证书签发给客户端设备使用的数字证书,用于客户端和服务端连接时,服务端对客户端进行安全认证。认证通过后服务端和客户端可基于证书内的加密密钥进行安全通信,若认证不通过则服务端拒绝客户端接入。
  • 使用设备证书认证时,必须保证签发该设备证书的CA证书已在MQTT服务端中注册。
  • 客户端设备使用设备证书进行接入认证时,服务端会根据已注册的CA证书验证设备证书是否正确,若CA证书和设备证书匹配成功,则客户端认证通过,且系统会将该设备证书自动注册到服务端中。

双向SSL/TLS安全连接

作为基于现代密码学公钥算法的安全协议,TLS/SSL 能在计算机通讯网络上保证传输安全,很多MQTT Broker 内置对 TLS/SSL 的支持,包括支持单/双向认证、X.509 证书、负载均衡 SSL 等多种安全认证。

SSL/TLS 安全优势

  • 强认证。 用 TLS 建立连接的时候,通讯双方可以互相检查对方的身份。在实践中,很常见的一种身份检查方式是检查对方持有的 X.509 数字证书。这样的数字证书通常是由一个受信机构颁发的,不可伪造。
  • **保证机密性。**TLS 通讯的每次会话都会由会话密钥加密,会话密钥由通讯双方协商产生。任何第三方都无法知晓通讯内容。即使一次会话的密钥泄露,并不影响其他会话的安全性。
  • 完整性。 加密通讯中的数据很难被篡改而不被发现。

SSL/TLS 协议

TLS/SSL 协议下的通讯过程分为两部分,第一部分是握手协议。握手协议的目的是鉴别对方身份并建立一个安全的通讯通道。握手完成之后双方会协商出接下来使用的密码套件和会话密钥;第二部分是 record 协议,record 和其他数据传输协议非常类似,会携带内容类型,版本,长度和荷载等信息,不同的是它所携带的信息是加密了的。
下面的图片描述了 TLS/SSL 握手协议的过程,从客户端的 “hello” 一直到服务器的 “finished” 完成握手。有兴趣的同学可以找更详细的资料看。
在这里插入图片描述

**SSL/TLS 证书准备 **

  在双向认证中,一般都使用自签名证书的方式来生成服务端和客户端证书,因此本文就以自签名证书为例。

通常来说,我们需要数字证书来保证 TLS 通讯的强认证。数字证书的使用本身是一个三方协议,除了通讯双方,还有一个颁发证书的受信第三方,有时候这个受信第三方就是一个 CA。和 CA 的通讯,一般是以预先发行证书的方式进行的。也就是在开始 TLS 通讯的时候,我们需要至少有 2 个证书,一个 CA 的,一个 MQTT服务端 的, MQTT服务端的证书由 CA 颁发,并用 CA 的证书验证。
在这里,我们假设您的系统已经安装了 OpenSSL。使用 OpenSSL 附带的工具集就可以生成我们需要的证书了。

使用OpenSSL创建生成CA证书、服务器、客户端证书及密钥

  1. 生成CA证书
  2. 生成服务器证书
  3. 生成客户端证书
  • 对于SSL单向认证:服务器需要CA证书、server证书、server私钥,客户端需要CA证。
  • 对于SSL双向认证:服务器需要CA证书、server证书、server私钥,客户端需要CA证书,client证书、client私钥。

各类证书与密钥文件后缀的解释

总得来说这些文件都与X.509证书和密钥文件有关,从文件编码上分,只有两大类:
PEM格式:使用Base64 ASCII进行编码的纯文本格式
DER格式:二机制格式
而CRT, CER,KEY这几种证书和密钥文件,它们都有自己的schema,在存储为物理文件时,既可以是PEM格式,也可以DER格式。
CER:一般用于windows的证书文件格式
CRT:一般用于Linux的证书,包含公钥和主体信息
KEY:一般用于密钥,特别是私钥, 与证书一一配对
打个比方:CER,CRT,KEY相当于论文,说明书等,有规定好的行文格式与规范,而PEM和DER相当于txt格式还是word格式。
CSR: Certificate Signing Request,即证书签名请求文件。证书申请者在生成私钥的同时也生成证书请求文件。把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件,也就是颁发给用户的证书。

证书生成

1.生成CA证书

1.创建CA证书私钥
openssl genrsa -out ca.key 2048
2.请求证书 证数各参数含义如下
  • C-----国家(Country Name)
  • ST----省份(State or Province Name)
  • L----城市(Locality Name)
  • O----公司(Organization Name)
  • OU----部门(Organizational Unit Name)
  • CN----产品名(Common Name)
  • emailAddress----邮箱(Email Address)
openssl req -new -sha256 -key ca.key -out ca.csr -subj "/C=CN/ST=SZ/L=SZ/O=C.X.L/OU=C.X.L/CN=CA/emailAddress=123456@test.com"
3.自签署证书
openssl x509 -req -days 36500 -sha256 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.crt

2.生成服务端证书

1.创建服务器私钥
openssl genrsa -out server.key 2048

新建 openssl.cnf 文件,

  • req_distinguished_name :根据情况进行修改,
  • alt_names:BROKER_ADDRESS 修改为 EMQ X 服务器实际的 IP 或 DNS 地址,例如:IP.1 = 127.0.0.1,或 DNS.1 = broker.xxx.com
  • 注意:IP 和 DNS 二者保留其一即可,如果已购买域名,只需保留 DNS 并修改为你所使用的域名地址。
[req]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext
x509_extensions    = v3_req
prompt             = no

[req_distinguished_name]
countryName             = CN
stateOrProvinceName     = SZ
organizationName        = C.X.L
organizationalUnitName  = C.X.L
commonName          = service

[req_ext]
subjectAltName = @alt_names

[v3_req]
subjectAltName = @alt_names

[alt_names]
IP.1 = 127.0.0.1
IP.2 = 192.168.5.249

2.请求证书

openssl req -new -sha256 -key server.key -config openssl.cnf -out server.csr

3.使用CA证书签署服务器证书

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256 -extensions v3_req -extfile openssl.cnf

4.验证服务端证书

openssl verify -CAfile ca.crt server.crt

5查看服务端证书

openssl x509 -noout -text -in server.crt
6.Netty需要支持PKCS8格式读取私钥
openssl pkcs8 -topk8 -nocrypt -in server.key -out pkcs8_key.pem

在这里插入图片描述

**注:**错误日志也很明确的打印了:at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351),采用PKCS8无法解析证书。这是因为部分MQTT broker使用的是netty,netty默认使用PKCS8格式对证书进行解析,然而我们使用openssl生成的服务端server.key是PKCS1格式的,所以MQTT broker采用PKCS8无法对证书进行解析。

问题处理

对证书进行格式转行,将PKCS1格式转换成PKCS8即可。
证书格式区别:

  1. PKCS1的文件头格式 -----BEGIN RSA PRIVATE KEY-----
  2. PKCS8的文件头格式 -----BEGIN PRIVATE KEY-----

生成客户端证书

1.生成客户端私钥
openssl genrsa -out client.key 2048
2.请求证书
openssl req -new -sha256 -key client.key -out client.csr -subj "/C=CN/ST=SZ/L=SZ/O=C.X.L/OU=C.X.L/CN=CLIENT/emailAddress=123456@test.com"
3.使用CA证书签署客户端证书
openssl x509 -req -days 36500 -sha256 -extensions v3_req -CA ca.cer -CAkey ca.key -CAserial ca.srl -CAcreateserial -in client.csr -out client.crt

4.验证服务端证书

openssl verify -CAfile ca.crt client.crt

5.查看服务端证书

openssl x509 -noout -text -in client.crt

证书转换

CRT转为PEM
#.key 转换成 .pem:
openssl rsa -in server.key -out server-key.pem
#.crt 转换成 .pem:
openssl x509 -in server.crt -out server.pem -outform PEM

既然PEM与DER只是编码格式上的不同,那么不管是证书还是密钥,都可以随意转换为想要的格式:

PEM转DER
openssl x509 -outform der -in server.pem -out server.der
DER专PEM
openssl x509 -inform der -in server.der -out server.crt

注:也可以直接生成PEM格式的证书,生成方式和CRT一样
区别:

// 生成CA证书
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.pem
// 生成服务端证书
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.pem -days 3650 -sha256 -extensions v3_req -extfile openssl.cnf
// 生成客户端证书
openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client.pem

SSL/TLS 双向连接的启用及验证

1.EMQX

在 EMQ X 中 mqtt:ssl 的默认监听端口为 8883。
将前文中通过 OpenSSL 工具生成的 server.crt 、server.key 及 ca.crt 文件拷贝到 EMQ X 的 etc/certs/ 目录下,并参考如下配置修改 emqx.conf:

## listener.ssl.$name is the IP address and port that the MQTT/SSL
## Value: IP:Port | Port
listener.ssl.external = 8883

## Path to the file containing the user's private PEM-encoded key.
## Value: File
listener.ssl.external.keyfile = etc/certs/server.key

## Path to a file containing the user certificate.
## Value: File
listener.ssl.external.certfile = etc/certs/emqx.pem

## Path to the file containing PEM-encoded CA certificates. The CA certificates
## Value: File
listener.ssl.external.cacertfile = etc/certs/ca.pem

## A server only does x509-path validation in mode verify_peer,
## as it then sends a certificate request to the client (this
## message is not sent if the verify option is verify_none).
##
## Value: verify_peer | verify_none
listener.ssl.external.verify = verify_peer
2.MQTT 连接测试

参照下图在 MQTT X 中创建 MQTT 客户端(Host 输入框里的 127.0.0.1 需替换为实际的 EMQ X 服务器 IP)
在这里插入图片描述

此时 Ce

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程识堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值