MQTT mit TLS 1.3 verkürzt den Handshake, entfernt schwache Kryptografie und vereinfacht die Wahl der Cipher Suites, doch bei batteriebetriebenen Geräten entstehen die eigentlichen Kosten an anderer Stelle. Dieser Artikel erklärt, was sich zwischen TLS 1.2 und 1.3 für MQTT-Verbindungen tatsächlich ändert, welche Cipher Suites Sie zulassen sollten, wie Sie messen, was Ihre Verbindung aushandelt, und wie Sie Python-, Node.js- und Mosquitto-Clients sinnvoll konfigurieren.
Warum die TLS-Version für MQTT wichtig ist
MQTT läuft über eine langlebige TCP-Verbindung. Ein Gerät verbindet sich einmal, führt einen TLS-Handshake durch und tauscht dann stunden- oder tagelang kleine Nachrichten aus. Bei ständig verbundenen Geräten fallen die Handshake-Kosten also selten an, bei Geräten, die schlafen und sich neu verbinden, etwa Batteriesensoren, die alle paar Minuten aufwachen, dagegen sehr oft. Bei diesen Geräten dominieren Handshake-Roundtrips und die CPU-Zeit für Public-Key-Operationen den Energieverbrauch, und die Wahl von TLS-Version und Cipher Suite spielt eine große Rolle.
Wenn Sie neu im Absichern von MQTT-Verbindungen sind, beginnen Sie mit unserem Leitfaden zur MQTT-TLS-Konfiguration und kehren Sie für die Feinabstimmung hierher zurück.
TLS 1.2 vs. TLS 1.3 auf einen Blick
| Aspekt | TLS 1.2 | TLS 1.3 |
|---|---|---|
| Roundtrips beim vollständigen Handshake | 2 vor Anwendungsdaten | 1 vor Anwendungsdaten |
| Wiederaufgenommener Handshake | 1 Roundtrip (Session ID oder Ticket) | 1 Roundtrip (PSK), optional 0-RTT |
| Schlüsselaustausch | RSA oder (EC)DHE | Nur (EC)DHE, immer mit Forward Secrecy |
| Cipher Suites | Dutzende, viele schwach oder veraltet | Fünf definiert, drei weit verbreitet |
| Zertifikat im Handshake verschlüsselt | Nein | Ja |
| CBC-Modus, RC4, SHA-1, statisches RSA | Erlaubt (je nach Konfiguration) | Entfernt |
Für einen Client an einer Mobilfunkverbindung mit hoher Latenz, etwa ein Gateway an einer abgesetzten Pumpstation oder Windkraftanlage, macht sich ein eingesparter Roundtrip bei jedem Verbindungsaufbau bemerkbar. Für ein Gerät im lokalen Netzwerk ist die Einsparung im Vergleich zum kryptografischen Aufwand gering.
Woher die Handshake-Kosten wirklich kommen
Auf einem Mikrocontroller dominieren drei Operationen einen vollständigen Handshake:
- Schlüsselaustausch: eine ECDHE-Berechnung, typischerweise auf X25519 oder der Kurve P-256. Sie findet in beiden TLS-Versionen statt.
- Zertifikatsprüfung: das Prüfen der Signaturen in der Kette des Servers. Die Prüfung von RSA-Signaturen ist günstig; ECDSA-Prüfungen kosten auf dem Client mehr, dafür sind ECDSA-Zertifikate kleiner.
- Netzwerk-Roundtrips: Jeder davon hält das Funkmodul wach.
TLS 1.3 reduziert die Roundtrips, entfernt aber nicht die Public-Key-Operationen. Der größte Gewinn für Geräte, die sich häufig neu verbinden, ist meist die Session Resumption, die die Zertifikatsprüfung überspringt und im PSK-Modus von TLS 1.3 mit Schlüsselaustausch weiterhin Forward Secrecy bietet. Prüfen Sie, ob Ihr TLS-Stack und Ihr Broker sie beide unterstützen, bevor Sie sich darauf verlassen.
Auch Hardwarebeschleunigung zählt. Die ESP32-Familie beschleunigt über mbedTLS AES, SHA und die Langzahlarithmetik für RSA und ECC, was beide TLS-Versionen darauf praxistauglich macht. Kleinere Mikrocontroller ohne Beschleunigung profitieren unter Umständen von ChaCha20-Poly1305, das in reiner Software schnell ist.
Cipher Suites für MQTT mit TLS 1.3
TLS 1.3 trennt die Cipher Suite (symmetrische Verschlüsselung und Hash) vom Schlüsselaustausch und den Signaturalgorithmen. Die Suites, denen Sie in der Praxis begegnen:
TLS_AES_128_GCM_SHA256: verpflichtend zu implementieren, schnell mit AES-Hardware, ein guter Standard.TLS_AES_256_GCM_SHA384: größerer Schlüssel, etwas langsamer, oft aus Richtliniengründen gewählt.TLS_CHACHA20_POLY1305_SHA256: hervorragend auf CPUs ohne AES-Beschleunigung.
Alle drei bieten authentifizierte Verschlüsselung und gelten als stark. Sie müssen sie selten einschränken. Die beiden übrigen für TLS 1.3 definierten Suites (CCM-Varianten) kommen vor allem in ressourcenbeschränkten Umgebungen vor.
Für TLS 1.2, falls Sie es noch unterstützen müssen, lassen Sie nur AEAD-Suites mit Forward Secrecy zu:
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
Vermeiden Sie Suites mit CBC, RC4, 3DES, NULL, EXPORT oder solche mit statischem RSA-Schlüsselaustausch (Namen, die mit AES ohne ECDHE beginnen).
Messen, was Ihre Verbindung aushandelt
Gehen Sie nie davon aus, welche Version ein Broker unterstützt; messen Sie es. OpenSSL kann jede Version erzwingen und das Ergebnis melden:
# Die beste Version aushandeln, die beide Seiten unterstützen
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -brief </dev/null
# TLS 1.3 erzwingen
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -tls1_3 -brief </dev/null
# TLS 1.2 erzwingen
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -tls1_2 -brief </dev/null
Die Zeilen Protocol version und Ciphersuite zeigen das Ergebnis. Führen Sie dieselben Tests gegen jeden Broker aus, den Sie evaluieren, und wiederholen Sie sie nach Broker- oder Bibliotheks-Upgrades, denn die unterstützten Versionen können sich im Laufe der Zeit ändern.
Um Handshakes aus einem Skript heraus zu messen, misst dieses Python-Snippet die Latenz von Verbindungsaufbau plus Handshake:
import socket
import ssl
import time
HOST, PORT = "broker.connectmq.com", 8883
def handshake(version: ssl.TLSVersion) -> None:
ctx = ssl.create_default_context()
ctx.minimum_version = version
ctx.maximum_version = version
start = time.perf_counter()
try:
with socket.create_connection((HOST, PORT), timeout=10) as sock:
with ctx.wrap_socket(sock, server_hostname=HOST) as tls:
elapsed = (time.perf_counter() - start) * 1000
print(f"{tls.version()} {tls.cipher()[0]} {elapsed:.1f} ms")
except ssl.SSLError as exc:
print(f"{version.name} not negotiated: {exc.reason}")
for v in (ssl.TLSVersion.TLSv1_2, ssl.TLSVersion.TLSv1_3):
for _ in range(3):
handshake(v)
Führen Sie es mehrmals aus; der Netzwerk-Jitter ist auf einer schnellen Verbindung meist größer als der Unterschied zwischen den Versionen.
Clients konfigurieren
Die sicherste Client-Richtlinie lautet „TLS 1.2 und neuer zulassen, die neueste bevorzugen“. So können Client und Server die beste gemeinsame Version wählen.
Python (paho-mqtt 2.x)
import ssl
import paho.mqtt.client as mqtt
ctx = ssl.create_default_context() # prüft Kette und Hostname
ctx.minimum_version = ssl.TLSVersion.TLSv1_2 # alles Ältere ablehnen
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="py-tls13-c71e")
client.tls_set_context(ctx)
# client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.connect("broker.connectmq.com", 8883)
client.loop_start()
client.publish("connectmq/demo/c71e/tls", "negotiated securely", qos=1).wait_for_publish()
client.loop_stop()
client.disconnect()
Pythons set_ciphers() wirkt nur auf TLS 1.2 und älter; TLS-1.3-Suites werden über die OpenSSL-Standards verwaltet, die bereits solide sind.
Node.js (MQTT.js v5)
const mqtt = require("mqtt");
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
clientId: "node-tls13-c71e",
protocolVersion: 5,
minVersion: "TLSv1.2", // wird an tls.connect von Node durchgereicht
});
client.on("connect", () => {
const sock = client.stream;
console.log("TLS:", sock.getProtocol(), sock.getCipher().name);
client.end();
});
Mosquitto als selbst gehosteter Broker
Wenn Sie Ihren eigenen Mosquitto-Broker betreiben, kontrollieren Sie die Serverseite:
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
cafile /etc/mosquitto/certs/chain.pem
tls_version tlsv1.2
ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
ciphers_tls1.3 TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384
In Mosquitto legt tls_version die minimal akzeptierte Version am Listener fest. Einen Server ausschließlich auf TLS 1.3 zu beschränken, ist verlockend, sperrt aber ältere Firmware und Embedded-TLS-Stacks aus, die nur TLS 1.2 unterstützen.
Ressourcenarme Geräte: praktische Tipps
- Halten Sie Verbindungen offen. Ein Handshake pro Tag ist günstiger als jede Optimierung eines Handshakes pro Minute.
- Nutzen Sie Session Resumption, wo Ihr Stack sie unterstützt, für Geräte, die schlafen müssen.
- Aktivieren Sie Hardware-Kryptografie in der Konfiguration Ihres SDKs.
- Prüfen Sie den TLS-1.3-Status Ihres Stacks. Aktuelle mbedTLS-Versionen, die ESP-IDF nutzt, lassen sich als Konfigurationsoption mit TLS-1.3-Unterstützung bauen; ältere SDKs bieten nur TLS 1.2, das mit den oben genannten Suites weiterhin sicher ist.
- Codieren Sie keine einzelne Version fest in die Firmware. Lassen Sie die Aushandlung zu, damit Geräte weiter funktionieren, wenn sich Server ändern.
- Vermeiden Sie 0-RTT für Befehle. Early Data kann wiederholt werden, was bei Aktorbefehlen gefährlich ist.
Der Leitfaden zum ESP32 Certificate Pinning behandelt die Zertifikatsseite von Embedded-TLS, und MQTT-TLS-Handshake-Fehler beheben hilft, wenn die Versionsaushandlung schiefgeht.
Checkliste für die Sicherheitsrichtlinie
Nutzen Sie diese Liste, wenn Sie die TLS-Richtlinie für ein MQTT-Projekt schreiben:
- Minimale Protokollversion: TLS 1.2 auf Clients, TLS 1.3 erlaubt und bevorzugt.
- TLS-1.2-Suites: nur ECDHE-Schlüsselaustausch mit AES-GCM oder ChaCha20-Poly1305.
- TLS-1.3-Suites: Bibliotheksstandards, sofern keine Richtlinie AES-256 verlangt.
- Zertifikatsprüfung und Hostname-Prüfung: immer aktiv.
- Reconnect-Strategie: langlebige Verbindungen mit Backoff, keine Verbindung pro Nachricht.
- Resumption: aktiviert, wo der Stack sie unterstützt, für schlafende Geräte.
- Überprüfung: die OpenSSL-Versionstests nach jedem Broker-, Bibliotheks- oder Firmware-Upgrade wiederholen.
Eine kurze, schriftlich festgehaltene Richtlinie erleichtert Audits und verhindert, dass einmalige „vorübergehende“ Ausnahmen, etwa eine deaktivierte Zertifikatsprüfung, in die Produktion gelangen. In der industriellen Automatisierung lässt sich eine solche Richtlinie den Anforderungen an sichere Kommunikation aus IEC 62443 zuordnen, und für Betreiber im Geltungsbereich von NIS2 oder Hersteller vernetzter Produkte unter dem EU Cyber Resilience Act ist sie ein nachvollziehbarer Baustein der Sicherheitsdokumentation.
Die Server-Feinabstimmung einem verwalteten MQTT-Broker überlassen
Bei einem selbst betriebenen Broker müssen Sie Protokoll-Abkündigungen, Cipher-Empfehlungen und Zertifikatserneuerungen selbst verfolgen. Ein verwalteter MQTT-Broker übernimmt die Serverseite für Sie. ConnectMQ stellt TLS auf Port 8883 und Secure WebSocket auf 8084 mit einem Let's-Encrypt-Zertifikat bereit, sodass Sie nur die obige Client-Richtlinie brauchen: Zertifikat prüfen, TLS 1.2 und neuer zulassen und die Aushandlung die beste Option wählen lassen. Nutzen Sie den öffentlichen MQTT-Broker, um die Messungen aus diesem Artikel aus Ihrem eigenen Netzwerk durchzuführen; er ist für Tests gedacht, nicht für Produktionsdaten.
Starten Sie mit ConnectMQ
Registrieren Sie sich bei ConnectMQ unter app.connectmq.com, wählen Sie den kostenlosen Serverless-Plan ohne Kreditkarte und erstellen Sie einen Broker. Richten Sie die obigen Python- oder Node.js-Beispiele mit Ihren generierten Zugangsdaten darauf aus und prüfen Sie, was Ihre Verbindung aushandelt.
Häufig gestellte Fragen
Ist TLS 1.2 für MQTT noch sicher?
Ja, wenn es auf ECDHE-Schlüsselaustausch mit AEAD-Ciphern wie AES-GCM oder ChaCha20-Poly1305 beschränkt ist. Lassen Sie TLS 1.3 parallel zu, damit Clients es nutzen, wenn es verfügbar ist.
Verringert TLS 1.3 den Overhead von MQTT-Nachrichten?
Nicht nennenswert. Der Overhead pro Record ist ähnlich; die Hauptgewinne sind ein kürzerer Handshake, stärkere Standards und verschlüsselte Zertifikate.
Welche TLS-1.3-Cipher-Suite sollten IoT-Geräte verwenden?
TLS_AES_128_GCM_SHA256 auf Hardware mit AES-Beschleunigung, TLS_CHACHA20_POLY1305_SHA256 auf CPUs ohne. Beide sind stark.
Sollte ich 0-RTT Early Data mit MQTT verwenden?
In der Regel nicht. Early Data kann von einem Angreifer wiederholt werden, und MQTT-Clients gewinnen wenig, da Verbindungen langlebig sind.



