← Back to IoT Blog
IoT Security 28 min read

MQTT Security with TLS

Secure your MQTT communication with TLS/SSL encryption. Learn certificate generation, broker configuration, and client authentication for encrypted IoT messaging.

Why TLS for MQTT?

Standard MQTT (port 1883) sends data in plaintext. TLS encryption (port 8883) protects:

What TLS Protects:
  • Username/password credentials
  • Sensor data payloads
  • Control commands
  • Client IDs and topics
  • Prevents man-in-the-middle attacks

Generate Certificates

Create your own Certificate Authority (CA) and server certificates:

# Create CA private key
openssl genrsa -out ca.key 2048

# Create CA certificate
openssl req -new -x509 -days 365 -key ca.key -out ca.crt \
  -subj "/C=US/ST=State/L=City/O=MyOrg/CN=MyCA"

# Create server private key
openssl genrsa -out server.key 2048

# Create CSR (Certificate Signing Request)
openssl req -new -key server.key -out server.csr \
  -subj "/C=US/ST=State/L=City/O=MyOrg/CN=mqtt.example.com"

# Sign server certificate with CA
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out server.crt

# Create client certificate
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
  -subj "/C=US/ST=State/L=City/O=MyOrg/CN=client1"
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out client.crt

Mosquitto Broker Setup

Configure Eclipse Mosquitto for TLS:

# /etc/mosquitto/mosquitto.conf

# Listener for insecure connections (optional)
listener 1883

# Listener for TLS connections
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
cafile /etc/mosquitto/certs/ca.crt

# Require client certificates (mutual TLS)
require_certificate true
use_identity_as_username true

# TLS version (disable old versions)
tls_version tlsv1.2 tlsv1.3

# Cipher suites (strong ciphers only)
ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

# Restart Mosquitto
sudo systemctl restart mosquitto

ESP32 Client Configuration

#include 
#include 

// CA Certificate (PEM format)
const char* ca_cert = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiUMA0Gcg...
-----END CERTIFICATE-----
)EOF";

WiFiClientSecure espClient;
PubSubClient client(espClient);

void setup() {
  espClient.setCACert(ca_cert);
  
  // Optional: Client certificate for mutual TLS
  // espClient.setCertificate(client_cert);
  // espClient.setPrivateKey(client_key);
  
  client.setServer("mqtt.example.com", 8883);
  
  if (client.connect("ESP32_Client", "username", "password")) {
    Serial.println("Connected with TLS!");
  }
}

Client Certificate Authentication

Mutual TLS (mTLS) provides strongest security:

Auth MethodSecurityComplexity
Username/PasswordMediumLow
TLS Server AuthHighMedium
mTLS (Client Certs)Very HighHigh
# Mosquitto with mTLS
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
cafile /etc/mosquitto/certs/ca.crt

# Require client certificates
require_certificate true
use_identity_as_username true

# Client connects with certificate
# No password needed - cert proves identity

Testing & Verification

# Test TLS connection
openssl s_client -connect mqtt.example.com:8883 -CAfile ca.crt

# Test with mosquitto_pub
mosquitto_pub -h mqtt.example.com -p 8883 \
  --cafile ca.crt \
  --cert client.crt \
  --key client.key \
  -t "test/topic" -m "Hello TLS!"

# Check certificate expiry
openssl x509 -in server.crt -noout -dates

# Verify certificate chain
openssl verify -CAfile ca.crt server.crt
Security Checklist:
  • ✓ Use TLS 1.2 or 1.3 only
  • ✓ Disable weak cipher suites
  • ✓ Set certificate expiry alerts
  • ✓ Use strong key sizes (2048+ bit)
  • ✓ Protect private keys
  • ✓ Implement certificate rotation
  • ✓ Monitor for expired certs

Next Steps

  • Set up automatic certificate renewal
  • Implement certificate revocation (CRL/OCSP)
  • Add certificate monitoring
  • Use hardware secure element for key storage