MQTT Message Data Integrity - MQTT Security Fundamentals
Welcome to the ninth part of the MQTT Security Fundamentals series. In this post, we will discuss signing MQTT messages. Find out how digital signatures/MACs, and checksums for MQTT messages work and what problems they solve. To get the most out of this post, we recommend you read MQTT payload encryption first.
Note: While technically not 100% correct, to keep things simple, we use the word stamp to refer to digital signatures, MACs, and checksums in this blog post.
How do you check data integrity for MQTT messages?
It is important to check the integrity of messages that are sent to the broker from untrusted MQTT clients or MQTT clients that you don’t control (especially if you don’t use TLS). Data integrity checks let you ensure that third parties did not modify any content of your MQTT messages.
MQTT PUBLISH packets can contain a digital signature/MAC/checksum that verifies the contents of the packet. This calculated stamp is typically added to the payload (for example, at the beginning of the payload). The receiver of the packet can verify the integrity of the data by recalculating/validating the stamp. This validation assures that the message was not tampered with by a malicious third party.
Typically, the stamp is calculated with the following data:
- The MQTT PUBLISH payload
- The topic of the MQTT PUBLISH packet
The Quality of Service and the Message ID are not recommended for calculation of the stamp. Quality of Service downgrades can occur if the QoS of a subscription is smaller than the published QoS and Message IDs vary for the receiver and the sender of a packet. In these cases, the signature would no longer be valid. Therefore, it’s a good practice to only include the payload and the topic of the message for data integrity checks.
Mechanisms for creating and validating stamps
There are three popular ways to create stamps:
- Checksum / Hash Algorithms (for example, MD5, CRC, SHA1/2,…)
- MAC (for example, HMAC, CBC-MAC,…)
- Digital signatures
All of these mechanisms have their strengths and weaknesses. Although a discussion about these strengths and weaknesses is out of scope for this post, the following table gives you a good overview of the guarantees each mechanism offers:
Data Integrity: The recipient can make sure that the data was not modified (accidentally). Authentication: The recipient can make sure that the message originates from a trusted sender because only trusted parties have access to the key that is required to create and verify the stamp. Non-Repudiation: Only the sender of the message with access to the private key can create the stamp. Other parties can verify the signature with the public key but they cannot create the stamp themselves.
Using Checksums with MQTT
Checksum algorithms are typically very fast, even for large MQTT packets. However, if you don’t use TLS, we strongly recommended that you use a MAC algorithm or digital signatures instead of checksums. Checksums can get altered with the MQTT packet because an attacker only needs to know the checksum algorithm and can apply the algorithm after modifying the packet. There aren’t many good use cases for checksums in MQTT packets. If you have a good use case for checksums, let us know in the comments!
Using MACs with MQTT
Message Authentication Code Algorithms (for example, HMAC) are typically very fast compared to digital signatures. If the shared secret key is exchanged securely prior to the MQTT communication, these algorithms provide good security HMAC calculates the MAC with a cryptographic hash function and a cryptographic key. Only senders that know the secret key can create a valid stamp. The disadvantage of this method is that all clients who are aware of the secret key can sign and verify because the same key is involved in both processes.
HMACs work great with MQTT PUBLISH messages and can be used securely even if you don’t have TLS deployed. HMACs are pretty fast to calculate and don’t use many resources on constrained devices.
Using digital signatures with MQTT
Digital signatures use public / private key cryptography. The sender signs the message with its private key and the receiver validates the stamp (signature) with the public key of the sending client. Only the private key can create the signature. It is not possible for an attacker to fake the signature without the private key.
As we saw in the client certificate post, provisioning and revocation of public / private keys is a challenge and adds complexity to the system. Another challenge is that in Publish / Subscribe systems such as MQTT, the receiver of a message is usually not aware of the identity of the sender. Communication is decoupled via topics. However, if you can guarantee that only a specific client can publish to a specific topic (for example, through authorization mechanisms), digital signatures can be a good (and secure!) fit.
Data integrity and encryption
In last week’s post we saw how message encryption works with MQTT. Data integrity checks with stamps are a good addition to message encryption. Even if the attacker can decrypt the message (and encrypt it after modification), the integrity check still fails if the message was altered. Especially if you use MQTT without TLS, data integrity checks add an additional layer of security.
Data integrity checks and TLS
If TLS is deployed and proper authentication and authorization mechanisms are in place, data integrity checks don’t add much additional security. If you are using digital signatures with public / private key cryptography, the Non-Repudiation attribute may add additional security (particularly if you are dealing with very sensitive data and command PUBLISH packets).
That’s the end of part nine in our MQTT Security Fundamentals series. If you have any comments or suggestions, we would love to hear your feedback in the comments area below!
Subscribe to our newsletter and enjoy fresh content about MQTT and HiveMQ every month. If you prefer RSS, subscribe to our RSS feed.