使用 EMQX Cloud 实现物联网设备一机一密验证

暗物质计算
• 阅读 1516

数据安全是物联网应用的重中之重。各厂商常使用对称加密、非对称加密、数字签名、数字证书等方法来对设备进行认证,以防止非法设备的接入。在证书的使用方式上,有一型一密、一机一密等不同的方案,其中一机一密方案预先为每一个设备端设置唯一的设备证书,设备端与服务端通信时能够进行双向验证,验证通过后,设备端与服务端才进行正常的数据传输。相比于其他方案,一机一密能够做到针对每个设备的单独验证与授权,具有更高的安全性。

作为安全可靠的全托管 MQTT 消息云服务, EMQX Cloud 支持多种认证方式,包括基础认证(用户名/密码,客户端 ID/密码)及 JWT、PSK 和 X.509 证书认证,同时可配置外部数据库作为数据源验证认证信息。

本文将采用 Redis 作为认证数据源存储数据库,讲解如何通过设备端证书中包含的 Common Name 为验证信息,连接到 EMQX Cloud,实现客户端一机一密验证。若客户端证书中不带有指定唯一的 Common Name,则无法通过认证。

通过本文,读者可以为其物联网设备实现一机一密、设备与服务器双向身份认证和建立安全通道的能力,有效防止伪造设备攻击、设备密钥被破解、伪造服务器指令、监听或篡改关键信息、通过设备产线安全漏洞窃取密钥等攻击手段。

操作流程

一、配置 TLS/SSL 双向认证

1、准备工作

  1. 购买服务器证书,并将其域名解析到部署连接地址。

    使用 EMQX Cloud 实现物联网设备一机一密验证

  2. 生成客户端 root ca 自签名证书,使用自签名 root ca 证书签发客户端证书需确保 Common Name 唯一。

    # CA 证书生成 client-ca.crt,subj 依据实际使用情况调整。
    openssl req \
        -new \
        -newkey rsa:2048 \
        -days 365 \
        -nodes \
        -x509 \
        -subj "/C=Common Name/O=EMQ Technologies Co., Ltd/Common Name=EMQ CA" \
        -keyout client-ca.key \
        -out client-ca.crt
    
    # 客户端秘钥生成 client.key
    openssl genrsa -out client.key 2048
    
    # 生成客户端证书请求文件 client.csr,Common Name 为客户端携带认证信息
    openssl req -new -key client.key -out client.csr -subj "/Common Name=346a004d-1dab-4016-bb38-03cca7094415"
    
    # 用 CA 证书给客户端证书签名,生成 client.crt
    openssl x509 -req -days 365 -sha256 -in client.csr -CA client-ca.crt -CAkey client-ca.key -CAcreateserial -out client.crt
    
    # 查看客户端端证书信息
    openssl x509 -noout -text -in client.crt
    
    # 验证证书
    openssl verify -CAfile client-ca.crt client.crt

2、配置流程

登录 EMQX Cloud 控制台 。进入部署详情,点击 +TLS/SSL 配置按钮,配置证书内容,您可以上传文件或者直接填写证书内容 TLS/SSL 认证类型:

① 单向认证:仅客户端验证服务端证书。

② 双向认证:客户端和服务端相互验证证书。

在本示例文档中我们以双向认证为例,在部署控制台填入以下内容:

① 公钥证书:服务端证书

② 证书链:证书链,通常第三方机构签发证书时会提供

③ 私钥:私有秘钥

④ 客户端 CA 证书:选择双向认证时,需要提供客户端的 CA 证书

使用 EMQX Cloud 实现物联网设备一机一密验证

填写完成后,点击确定,直至状态为运行中,即 TLS/SSL 双向认证配置完成。

二、配置 Redis 认证/访问控制

本文以 Redis 认证/访问控制为例,当然您也可以使用其他外部认证数据源,在本文所述场景中,比较推荐使用 Redis 认证/访问控制。

1、创建 VPC 对等连接

在 EMQX Cloud 部署详情页面,创建 VPC 对等连接,便于专业版部署内网访问到您方 Redis 认证数据库。

使用 EMQX Cloud 实现物联网设备一机一密验证

2、配置 Redis 认证/访问控制

  1. redis 配置

    在你的云服务器中,创建一个 Redis 服务。为了方便演示,这里使用 Docker 快速搭建。

    docker run -itd --name redis -p 6379:6379 redis:latest

    本示例配置数据有如下两种方式(二选一):

    HMSET  tls_domain:346a004d-1dab-4016-bb38-03cca7094415 password pubic
    HMSET  tls_subject:346a004d-1dab-4016-bb38-03cca7094415 password pubic

    使用 EMQX Cloud 实现物联网设备一机一密验证

  2. Redis 认证/访问控制配置

    进行身份认证时,EMQX Cloud 将使用当前客户端信息填充并执行用户配置的认证查询命令,查询出该客户端在 Redis 中的认证数据。

    可以在认证 SQL 中使用以下占位符,执行时 EMQX Cloud 将自动填充为客户端信息::

    • %u:用户名
    • %c:客户端 ID
    • %C:TLS 证书公用名(证书的域名或子域名),仅当 TLS 连接时有效
    • %d:TLS 证书 subject,仅当 TLS 连接时有效

    你可以根据业务需要调整认证查询命令,使用任意 Redis 支持的命令 (opens new window),但是任何情况下认证查询命令需要满足以下条件:

    ① 查询结果中第一个数据必须为 password,EMQX 使用该字段与客户端密码比对

    ② 如果启用了加盐配置,查询结果中第二个数据必须是 salt 字段,EMQX 使用该字段作为 salt(盐)值

    在部署中点击认证鉴权 - 外部认证授权 - Redis 认证/访问控制,点击配置认证,即可新建认证。

    认证查询命令有如下两种方式:

    HMGET tls_domain:%C password
    HMGET tls_subject:%d password

    即设备需携带客户端证书、客户端秘钥和其 Common Name 、password 的方式进行身份验证。

    使用 EMQX Cloud 实现物联网设备一机一密验证

测试验证

我们使用 MQTT X 模拟客户端携带以下信息连接到 EMQX Cloud。

① 服务端 CA

② Common Name 为 346a004d-1dab-4016-bb38-03cca7094415 的客户端证书、客户端秘钥

③ password:public

使用 EMQX Cloud 实现物联网设备一机一密验证

点击 右上角 connect,出现 connected 表示已连接成功。至此,带有指定 common name 的设备已成功连接至 EMQX Cloud,即一机一密设备通过验证并连接至 EMQX Cloud 已成功。

使用 EMQX Cloud 实现物联网设备一机一密验证

结语

至此我们完成了 EMQX Cloud 的客户端一机一证书验证流程,成功连接到部署。相比于其他方案,一机一密能够做到针对每个设备的单独验证与授权,具有更高的安全性,若您也为您的每一个物联网设备设置了唯一的访问凭证,可以参考本文进行配置。

版权声明: 本文为 EMQ 原创,转载请注明出处。

原文链接:https://www.emqx.com/zh/blog/one-device-one-secret-authentication-for-iot-devices-with-emqx-cloud

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
物联网云平台盘点
物联网云平台是一个专门为物联网定制的云平台,物联网与普通的互联网是不同的:物联网终端设备比普通互联网手机端,电脑端多出几个数量级;普通互联网对http,https协议访问相对单一,而对https有些设备不能访问,需要轻量级的访问协议。物联网场景的多样,使得没有任何一个产品能解决所有问题。物联网平台也一样,今天来盘点一下国内一些物联网平台的主要特点。一站式托管
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
(绝对有用)iOS获取UUID,并使用keychain存储
UDID被弃用,使用UUID来作为设备的唯一标识。获取到UUID后,如果用NSUserDefaults存储,当程序被卸载后重装时,再获得的UUID和之前就不同了。使用keychain存储可以保证程序卸载重装时,UUID不变。但当刷机或者升级系统后,UUID还是会改变的。但这仍是目前为止最佳的解决办法了,如果有更好的解决办法,欢迎留言。(我整理的解决办法的参
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0