[聚合文章] [译]MQTT安全基础:TLS/SSL

消息系统 2017-10-19 15 阅读

欢迎来到MQTT安全基础系列的第五部分。在最近几周的文章中关注了应用层的身份验证和授权后,本周的主题是使用TLS的传输加密。

我们将看看为什么TLS / SSL对于安全的MQTT解决方案是有利的,我们将讨论使用MQTT传输加密时的最佳做法。

注:本文翻译自: MQTT Security Fundamentals: TLS / SSL

什么是TLS

TLS(传输层安全)和SSL(安全套接字层)在客户端和服务器之间提供安全的通信通道。其核心是TLS和SSL是使用握手机制协商各种参数以在客户端和服务器之间建立安全连接的加密协议。握手完成后,建立客户端与服务器之间的加密通信,没有攻击者可以窃听通信的任何部分。服务器提供X509证书,通常由受信任的机构颁发,客户端用它来验证服务器的身份。

为什么TLS很重要?

想像你正在发送明信片。很明显,该卡的收件人是谁,邮递员将确保该卡到达。然而,没有什么可以阻止邮递人员读卡的内容,实际上涉及交付明信片的每个人都可以阅读内容。如果你有一个恶意的邮递员,他甚至可以改变明信片中的一些内容!

以上说明的情况对于一般的计算机网络和特别是互联网也是如此。如果你使用纯TCP/IP,就像发送明信片。 TCP数据包将在达到目标之前经过大量基础架构组件(路由器,防火墙,Internet交换点等)。所有参与者之间现在可以以明文形式读取您的数据包的内容,甚至可以修改它。这不是一个虚构的场景,最近的历史表明,互联网流量一直被情报机构窃听。虽然大多数攻击者没有太多的资源来窃听你的连接,但复杂的攻击者并不是太难以执行“中间人攻击”。

所以TLS就是提供一个安全的通信信道。使用TLS,可以肯定的是,第三方不能读取或更改通信内容*。

假设使用安全的密码套件,并且对所使用的TLS版本没有未知的攻击。

MQTT与TLS

MQTT依赖于TCP作为传输协议,这意味着默认情况下连接不使用加密通信。为了加密整个MQTT通信,大多数MQTT代理(如HiveMQ)允许使用TLS而不是纯TCP。如果使用MQTT CONNECT数据包的用户名和密码字段进行身份验证和授权机制,则应强烈考虑使用TLS。

端口8883对于安全的MQTT连接是标准化的。IANA的标准化名称是“secure-mqtt”,端口8883专用于基于TLS的MQTT。

TLS开销

然而,一如以往,在使用基于TLS的MQTT时存在一个缺点:安全性在CPU使用率和通信开销方面是有代价的。虽然代理的附加CPU使用率通常可以忽略不计,但对于非专门针对计算密集型任务而设计的非常受限的设备来说,这可能是一个问题。诸如Session Resumption之类的技术可以大大提高TLS的性能。

如果MQTT客户端连接预期是短暂的,则TLS握手的通信开销可能很大。虽然这取决于许多因素,TLS握手需要多少带宽,但一些测量显示,建立新的TLS连接可能需要高达几千字节的带宽。由于每个数据包在使用TLS时都被加密,与未加密的数据包相比,电线上的数据包也有额外的开销。

因此,如果你使用长存TCP连接与MQTT(你应该!),TLS开销,特别是TLS握手开销可能是微不足道的。如果您正在处理许多重新连接,并且无法使用会话恢复,那么开销可能很大,特别是如果您发布非常小的MQTT消息。如果电线上的每个字节对您的用例计数,则由于开销,TLS可能不是你的最佳选择,因此请务必测量TLS用于你的用例的开销。

会话恢复

我们已经听说过以前段落中的TLS会议恢复。简而言之,TLS会话恢复技术允许在重新连接到服务器之后重用已经协商的TLS会话,因此客户端和服务器不需要再次完成TLS握手。重要的是要注意,并不是所有的TLS库实现了所有会话恢复技术,有些甚至没有实现任何会话恢复机制。

有两个会话恢复机制:

  • Session IDs:服务器将秘密状态与会话ID一起存储。当客户端重新连接时,它提供会话ID,可以恢复会话。

  • Session Tickets:服务器的秘密状态被发送到客户端,并且仅使用服务器知道的秘密密钥进行加密。重新连接时,客户端将此故障单发送回服务器。如果服务器可以再次对内容进行解密,会话将恢复为机密中包含的状态。

HiveMQ支持Session IDs,但不支持Session Tickets。

受限设备上的TLS

由于资源不足,有时TLS对于受限设备是不可行的。根据使用的密码,TLS可能非常计算密集,可能需要几十千字节的内存。如果您的设备无法使用TLS,则应考虑为PUBLISH消息使用有效负载加密,并且至少应在客户端的CONNECT消息中对密码进行散列或加密。更多关于该主题的下一篇博客文章。

它也可以是查看TLS-PSK密码套件的选项,因为它们避免了CPU密集型公钥操作。TLS-PSK密码尚未被广泛采用,因此您需要重新检查TLS库是否支持此功能。

我应该总是使用TLS与MQTT?

Short answer:是的,如果可以的话。

Long answer:如果您能够负担CPU和带宽的开销,那么安全的通信通道是无价的。如果在客户端和服务器端正确实施TLS,则确保没有窃听者可以拦截您的通信,并获得对应用程序级身份验证和授权很重要的附加安全层。

最佳做法

如果可以的话,始终使用TLS

如果您能负担额外的带宽并且您的客户端具有足够的计算能力和TLS内存,那么始终使用TLS与MQTT。根据经验,总是使用加密的通信通道,也可以用于HTTP等其他协议。

使用最高可用的TLS版本

虽然TLS 1.0,TLS 1.1和TLS 1.2在实践中至少不会破坏(至少到现在为止),但您应该始终使用对您的MQTT客户端可行的最高TLS版本。事实上,对TLS 1.0和1.1有着众所周知的攻击,可以缓解这些攻击,有些则针对HTTP漏洞(如CRIME攻击)而设计。在撰写本文时,没有实际适用的攻击TLS 1.2。

不要使用SSLv3

不要使用SSLv3或任何以前的版本。POODLE攻击显示,SSLv3现在必须被视为破损坏。所有其他SSL版本也被认为是破坏的,不应该被使用。

始终验证X509证书链

为了防止中间人攻击,您的MQTT客户端验证来自MQTT代理的X509证书是非常重要的。一些恶意的客户端实现使用“允许全部”方法,通常与自签名服务器证书组合。永远不要这样做!做更多安全和验证证书总是值得的。

使用受信任CA的证书

使用受信任的CA的官方证书值得他们花费的额外费用,因为自签名的证书在许多TLS实现方面不能太好地运行,并且通常会导致例如错误的代码。不验证证书,造成中间人攻击的可能性。如果您的MQTT代理面向公开,则必须具有受信任的证书。如果您通过Websockets使用MQTT,则自签名证书不是最佳的,因为大多数现代Web浏览器不允许使用不受信任的证书进行websocket连接资源。

使用其他安全机制

除了TLS之外,使用额外的安全机制(如有效负载加密,有效载荷签名验证和授权机制)总是一个好主意。更安全的考虑通常不会有伤害。

只使用安全密码套件

使用TLS时可以使用许多不安全的密码套件。确保只允许安全的密码套件进行通信,否则可能会产生错误的安全感,因为有许多已知被破坏的密码套件。

我们希望您喜欢第五部分MQTT安全基础知识。下周我们将与TLS一起讨论X509客户端证书身份验证。

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。