增强认证 - MQTT 5.0 新特性

MQTT v5 带来了了很多新的特性,我们会尽量以通俗易懂的⽅方式展示这些特性,并探讨这些特性对开发者 的影响。到目前为止,我们已经探讨这些 MQTT v5 新特性,今天我们将继续讨论: 增强认证

在物联网的应用场景中,安全设计是非常重要的一个环节,敏感数据泄露或是边缘设备被非法控制等事故都是不可接受的,但是相比于其他应用场景,物联网项目还存在着以下局限:

  • 安全性与高性能之间不可以兼顾;
  • 加密算法需要更多的算力,而物联网设备的性能往往非常有限;
  • 物联网的网络条件常常要比家庭或者办公室的网络条件差许多。

为了解决上述问题,MQTT 协议 提供了简单认证和增强认证,方便在应用层验证设备。

简单认证

MQTT CONNECT 报文使用用户名和密码支持基本的网络连接认证,这个方法被称为简单认证。该方法也可以被用来承载其他形式的认证,例如把密码作为令牌(Token)传递。

服务器在收到 CONNECT 报文后,可以通过其包含的用户名和密码来验证客户端的合法性,保障业务的安全。

相比于增强认证,简单认证对于客户端和服务器的算力占用都很低,对于安全性要求不是那么高,计算资源紧张的业务,可以使用简单认证。

但是,在基于用户名和密码这种简单认证模型的协议中,客户端和服务器都知道一个用户名对应一个密码。在不对信道进行加密的前提下,无论是直接使用明文传输用户名和密码,还是给密码加个哈希的方法都很容易被攻击。

增强认证

基于更强的安全性考虑,MQTT v5 增加了新特性 增强认证,增强认证包含质询/响应风格的认证,可以实现对客户端和服务器的双向认证,服务器可以验证连接的客户端是否是真正的客户端,客户端也可以验证连接的服务器是否是真正的服务器,从而提供了更高的安全性。

增强认证依赖于认证方法和认证数据来完成整个认证过程,在增强认证中,认证方法通常为 SASL( Simple Authentication and Security Layer ) 机制,使用一个注册过的名称便于信息交换。但是,认证方法不限于使用已注册的 SASL 机制,服务器和客户端可以约定使用任何质询 / 响应风格的认证。

认证方法

认证方法是一个 UTF-8 的字符串,用于指定身份验证方式,客户端和服务器需要同时支持指定的认证方法。客户端通过在 CONNECT 报文中添加认证方法字段来启动增强认证,增强认证过程中客户端和服务器交换的报文都需要包含认证方法字段,并且认证方法必须与 CONNECT 报文保持一致。

认证数据

认证数据是二进制信息,用于传输加密机密或协议步骤的多次迭代。认证数据的内容高度依赖于认证方法的具体实现。

增强认证流程

相比于依靠 CONNECT 报文和 CONNACK 报文一次交互的简单认证,增强认证需要客户端与服务器之间多次交换认证数据,因此,MQTT v5 新增了 AUTH 报文来实现这个需求。增强认证是基于 CONNECT 报文、CONNACK 报文以及 AUTH 报文三种 MQTT 报文类型实现的,三种报文都需要携带认证方法与认证数据达成双向认证的目的。

要开启增强认证流程,需要客户端向服务器发送包含了认证方法字段的 CONNECT 报文,服务器收到了 CONNECT 报文后,它可以与客户端通过 AUTH 报文继续交换认证数据,在认证完成后向客户端发送 CONNACK 报文。

SCRAM 认证非规范示例

  • 客户端到服务端: CONNECT 认证方法="SCRAM-SHA-1",认证数据=client-first-data
  • 服务端到客户端: AUTH 原因码=0x18,认证方法="SCRAM-SHA-1",认证数据=server-first-data
  • 客户端到服务端: AUTH 原因码=0x18,认证方法="SCRAM-SHA-1",认证数据=client-final-data

  • 服务端到客户端: CONNACK 原因码=0,认证方法="SCRAM-SHA-1",认证数据=server-final-data

Kerberos 认证非规范示例

  • 客户端到服务端: CONNECT 认证方法="GS2-KRB5"
  • 服务端到客户端: AUTH 原因码=0x18,认证方法="GS2-KRB5"
  • 客户端到服务端: AUTH 原因码=0x18,认证方法="GS2-KRB5",认证数据=initial context token
  • 服务端到客户端: AUTH 原因码=0x18,认证方法="GS2-KRB5",认证数据=reply context token
  • 客户端到服务端: AUTH 原因码=0x18,认证方法="GS2-KRB5"
  • 服务端到客户端: CONNACK 原因码=0,认证方法="GS2-KRB5",认证数据=outcome of authentication

在增强认证的过程中,客户端与服务器需要进行多次认证数据的交换,每次交换都需要通过认证算法对认证数据进行加解密的计算,所以它需要更多的计算资源以及更稳定的网络环境,因此它并不适合算力薄弱、网络波动大的边缘设备,而支持增强认证的 MQTT 服务器 也需要准备更多的计算资源来应对大量的连接。

重新认证

增强认证完成之后,客户端可以在任意时间通过发送 AUTH 报文发起重新认证,重新认证开始后,同增强认证一样,客户端与服务器通过交换 AUTH 报文来交换认证数据,直到服务器向客户端发送原因码为 0x00( 成功) 的 AUTH 报文表示重新认证成功。需要注意的是,重新认证的认证方法必须与增强认证一致。

在重新认证的过程中,客户端和服务器的其他报文流可以继续使用之前的认证。

关注我们获取最新动态

推荐阅读

EMQ X 与 RabbitMQ 消息服务器 MQTT 性能对比(上)

本文深入分析了 EMQ X 以及 RabbitMQ 在核心架构上的侧重,并据此分析了它们为 MQTT 集群模式表现带来的不同影响。

EMQ X 与 RabbitMQ 消息服务器 MQTT 性能对比(下)

本文详细解读了造成上篇压力测试结果存在差异的三个原因:节点间通讯的方式、消息流架构的方式、队列的使用。

如何在 Node.js 项目中使用 MQTT

本文主要介绍如何在 Node.js 项目中使用 MQTT 实现客户端与 MQTT 服务器的连接、订阅、取消订阅、收发消息等功能。

Shifan Yu 2021-08-26