Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home IoT & Smart Home

IoT Security: TLS/SSL for ESP32 MQTT Connections

IoT Security: TLS/SSL for ESP32 MQTT Connections

March 11, 2026 /Posted byJayesh Jain / 0

IoT security TLS SSL ESP32 MQTT connection is a topic that every serious IoT developer in India must master before deploying devices in production. Whether you are building a smart home controller, an industrial monitoring system, or a connected agriculture sensor, leaving your MQTT data unencrypted is a critical security risk. In this comprehensive guide, you will learn how to implement TLS 1.2/1.3 encryption on your ESP32’s MQTT communication — from obtaining certificates to writing production-ready Arduino code.

Table of Contents

  1. Why TLS/SSL Matters for ESP32 MQTT
  2. TLS/SSL Basics: Certificates and Keys
  3. MQTT Broker Setup: Mosquitto with TLS
  4. ESP32 Arduino Code: WiFiClientSecure + PubSubClient
  5. Storing Certificates Safely on ESP32
  6. Connecting to Cloud MQTT Brokers (HiveMQ, AWS IoT)
  7. Common TLS Errors and How to Fix Them
  8. Frequently Asked Questions

Why TLS/SSL Matters for ESP32 MQTT

MQTT over plain TCP (port 1883) sends all data, including device credentials and sensor readings, in clear text. Anyone on the same network — or an attacker who can intercept Wi-Fi packets — can read your data, inject fake messages, or impersonate your devices. In India, with the rapid growth of smart home and industrial IoT deployments, this risk is very real.

TLS (Transport Layer Security, the successor to SSL) solves this by:

  • Encryption: All data is encrypted in transit — no eavesdropping possible
  • Authentication: Both client and server verify each other’s identity using certificates
  • Integrity: A message authentication code (MAC) ensures data is not tampered with in transit

MQTT over TLS uses port 8883 by default. The ESP32’s hardware-accelerated AES and SHA engines make TLS operations fast enough for real-time IoT applications while keeping power consumption low.

Ai Thinker ESP32-C3-01M Wi-Fi + BLE Module

Ai Thinker ESP32-C3-01M Wi-Fi + BLE Module

The ESP32-C3 supports hardware-accelerated TLS, making it ideal for secure MQTT IoT nodes. Its compact size suits always-on IoT deployments across India.

View on Zbotic

TLS/SSL Basics: Certificates and Keys

Before touching any code, you need to understand the certificate model. TLS uses asymmetric (public-key) cryptography to establish a secure channel:

File Purpose Who Has It
CA Certificate (ca.crt) Root certificate authority — used to verify the broker ESP32 client
Client Certificate (client.crt) Identifies this specific ESP32 device ESP32 client + broker
Client Key (client.key) Private key — never leave the device ESP32 client only
Server Certificate (server.crt) Identifies the MQTT broker Broker only

For a homelab or private deployment, you can create your own Certificate Authority (CA) using OpenSSL. For cloud brokers like HiveMQ Cloud or AWS IoT Core, they provide their own CA certificates.

Generate your own CA and certificates using these OpenSSL commands on Linux/Mac:

# Generate CA key and certificate
openssl genrsa -out ca.key 2048
openssl req -new -x509 -days 1826 -key ca.key -out ca.crt 
  -subj "/CN=MyIoT-CA/O=Zbotic/C=IN"

# Generate server key and CSR
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr 
  -subj "/CN=mqtt.yourdomain.in/O=Zbotic/C=IN"
openssl x509 -req -days 365 -in server.csr 
  -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt

# Generate client key and certificate
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr 
  -subj "/CN=esp32-device-001/O=Zbotic/C=IN"
openssl x509 -req -days 365 -in client.csr 
  -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt

MQTT Broker Setup: Mosquitto with TLS

Mosquitto is the most popular open-source MQTT broker and is free to run on any Linux server, Raspberry Pi, or cloud VM. Here is the configuration for enabling TLS with mutual authentication:

# /etc/mosquitto/conf.d/tls.conf
listener 8883
protocol mqtt

cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key

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

tls_version tlsv1.2

# Disable plain text port for security
listener 1883
allow_anonymous false

Restart Mosquitto after editing: sudo systemctl restart mosquitto

Test the TLS connection from your server before deploying to ESP32:

mosquitto_pub -h mqtt.yourdomain.in -p 8883 
  --cafile ca.crt --cert client.crt --key client.key 
  -t test/hello -m "TLS works!" -d

ESP32 Arduino Code: WiFiClientSecure + PubSubClient

The Arduino ESP32 core includes WiFiClientSecure, which provides TLS support using the Mbed TLS library bundled in ESP-IDF. Combined with the PubSubClient library, you get a complete secure MQTT client.

First, install PubSubClient via Arduino Library Manager (search for “PubSubClient” by Nick O’Leary).

Here is a complete, production-ready sketch:

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

// Wi-Fi credentials
const char* ssid     = "YourWiFiSSID";
const char* password = "YourWiFiPassword";

// MQTT Broker
const char* mqtt_broker = "mqtt.yourdomain.in";
const int   mqtt_port   = 8883;
const char* mqtt_topic  = "sensors/temperature";
const char* device_id   = "esp32-device-001";

// Certificates (stored in program memory)
const char* ca_cert = 
"-----BEGIN CERTIFICATE-----n"
"MIIDazCCAlOgAwIBAgIUXXXXXXXXXXXXXXXXXXXXXXXXXXXn"
// ... (full CA cert here)
"-----END CERTIFICATE-----n";

const char* client_cert = 
"-----BEGIN CERTIFICATE-----n"
// ... (full client cert here)
"-----END CERTIFICATE-----n";

const char* client_key = 
"-----BEGIN RSA PRIVATE KEY-----n"
// ... (full private key here)
"-----END RSA PRIVATE KEY-----n";

WiFiClientSecure espClient;
PubSubClient mqttClient(espClient);

void connectWiFi() {
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" Connected!");
  Serial.println(WiFi.localIP());
}

void connectMQTT() {
  espClient.setCACert(ca_cert);
  espClient.setCertificate(client_cert);
  espClient.setPrivateKey(client_key);

  mqttClient.setServer(mqtt_broker, mqtt_port);
  mqttClient.setCallback(messageCallback);

  while (!mqttClient.connected()) {
    Serial.print("Connecting to MQTT broker...");
    if (mqttClient.connect(device_id)) {
      Serial.println(" Connected!");
      mqttClient.subscribe("commands/esp32-001");
    } else {
      Serial.print(" Failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" Retrying in 5s");
      delay(5000);
    }
  }
}

void messageCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message on topic: "); Serial.println(topic);
  String msg = "";
  for (int i = 0; i < length; i++) msg += (char)payload[i];
  Serial.println(msg);
}

void setup() {
  Serial.begin(115200);
  connectWiFi();
  connectMQTT();
}

void loop() {
  if (!mqttClient.connected()) connectMQTT();
  mqttClient.loop();

  static unsigned long lastPublish = 0;
  if (millis() - lastPublish > 10000) {
    lastPublish = millis();
    float temp = 27.5; // Replace with real sensor reading
    String payload = String(temp);
    mqttClient.publish(mqtt_topic, payload.c_str());
    Serial.print("Published: "); Serial.println(payload);
  }
}
DHT11 Digital Relative Humidity and Temperature Sensor Module

DHT11 Digital Relative Humidity and Temperature Sensor Module

Pair this DHT11 with your ESP32 to publish real temperature and humidity data securely over TLS/MQTT to your IoT dashboard or cloud broker.

View on Zbotic

Storing Certificates Safely on ESP32

Embedding certificates as C string literals in your sketch is convenient for prototyping but not ideal for production. Here are better approaches for Indian IoT product developers:

SPIFFS / LittleFS Storage

Store certificate files on the ESP32’s flash filesystem and read them at runtime:

#include <LittleFS.h>

String readFile(const char* path) {
  File f = LittleFS.open(path, "r");
  if (!f) return "";
  String content = f.readString();
  f.close();
  return content;
}

// In setup():
LittleFS.begin(true);
String caCert     = readFile("/ca.crt");
String clientCert = readFile("/client.crt");
String clientKey  = readFile("/client.key");
espClient.setCACert(caCert.c_str());
espClient.setCertificate(clientCert.c_str());
espClient.setPrivateKey(clientKey.c_str());

Upload the certificate files using the Arduino LittleFS Data Upload Tool (available as a plugin for Arduino IDE 1.x or a standalone script for IDE 2.x).

NVS (Non-Volatile Storage)

For maximum security, store the private key in ESP32’s NVS partition, which can be encrypted using ESP32’s flash encryption feature. This prevents physical extraction of the private key even if someone reads the flash chip directly.

Connecting to Cloud MQTT Brokers (HiveMQ, AWS IoT)

HiveMQ Cloud (Free Tier): HiveMQ offers a free cloud MQTT broker that is popular with Indian hobbyists. It uses standard TLS with a public CA (no client certificates required for the free tier):

// HiveMQ Cloud — server-only TLS (no client cert)
espClient.setInsecure(); // OR load the ISRG Root X1 CA cert
mqttClient.setServer("your-cluster.hivemq.cloud", 8883);
mqttClient.connect("esp32-001", "your-username", "your-password");

AWS IoT Core: AWS IoT uses mutual TLS with per-device certificates issued by AWS. Download the root CA (Amazon Root CA 1), device certificate, and private key from the AWS IoT Console, then use the same WiFiClientSecure + PubSubClient pattern shown earlier. Set the MQTT endpoint to your unique xxxxxx.iot.ap-south-1.amazonaws.com endpoint on port 8883.

DHT20 SIP Packaged Temperature and Humidity Sensor

DHT20 SIP Packaged Temperature and Humidity Sensor

The DHT20 offers better accuracy than DHT11 and is perfect for publishing environmental data securely over TLS/MQTT to AWS IoT Core or any cloud broker.

View on Zbotic

Common TLS Errors and How to Fix Them

Error Cause Fix
-0x2700 MBEDTLS_ERR_X509_CERT_VERIFY_FAILED Wrong or expired CA certificate Replace ca.crt with correct CA; check cert expiry with openssl
-0x7200 SSL_PEER_CLOSE_NOTIFY Broker closed connection — often wrong client cert or key Verify client.crt was signed by the same CA as broker expects
Connection timeout on port 8883 Firewall blocking port 8883, or wrong broker hostname Open port 8883 in UFW/iptables; verify DNS from ESP32 network
Heap allocation failure / stack overflow TLS handshake needs ~40KB RAM — insufficient free heap Free up memory: remove unused libraries, increase stack size
time() returning 0 System time not set — TLS cert validation fails Add NTP sync before MQTT connect: configTime(0,0,"pool.ntp.org")

The NTP sync issue is particularly important: TLS certificate validation checks the current date against the certificate’s validity period. If the ESP32’s clock is wrong (it has no real-time clock by default), all TLS connections will fail with certificate errors. Always sync time via NTP at startup:

configTime(19800, 0, "pool.ntp.org", "time.nist.gov"); // IST = UTC+5:30 = 19800s
struct tm timeinfo;
getLocalTime(&timeinfo); // Block until time is synced

Frequently Asked Questions

Do I always need mutual TLS (client certificates) for ESP32 MQTT?

No. Mutual TLS (where both server and client authenticate with certificates) is the most secure option but also the most complex. For many deployments, server-only TLS (ESP32 verifies the broker’s certificate, but the broker does not require a client cert) combined with strong username/password authentication is sufficient. Cloud services like HiveMQ Cloud use this model. Only use mutual TLS when you need strong device-level identity verification — for example, when each ESP32 should only be able to publish to its own topic.

How much extra memory does TLS use on ESP32?

The TLS handshake requires approximately 40–60 KB of free heap memory. After the handshake is complete and the session is established, ongoing memory overhead is about 15–20 KB. The ESP32 typically has 300+ KB of free heap after booting, so TLS is feasible. However, if you are running BLE + WiFi + TLS + a large application, memory can become tight. The ESP32-S3 with its larger RAM (512 KB SRAM) is better suited for such demanding applications.

Can ESP8266 (D1 Mini) also use TLS/SSL MQTT?

Yes, but with significant limitations. ESP8266 has only 80 KB of usable heap, which makes TLS extremely tight. The BearSSL library (used by ESP8266 Arduino core) can do TLS, but you must use setCACert() with fingerprint verification or a minimal cipher suite to reduce memory usage. For new projects requiring TLS security, use ESP32 instead — it has much more RAM and hardware crypto acceleration.

How do I rotate certificates on deployed ESP32 devices?

Certificate rotation on deployed devices is a major challenge. Best practices: (1) Use OTA (Over-the-Air) updates to push new firmware with updated embedded certificates before the old ones expire. (2) Store certificates in SPIFFS/LittleFS and provide an OTA mechanism specifically for certificate files. (3) Set certificate validity to 2–5 years and schedule updates well in advance. (4) AWS IoT Core and similar platforms provide certificate rotation mechanisms through their device management APIs.

Is setInsecure() safe to use on ESP32?

espClient.setInsecure() disables certificate verification entirely. The data is still encrypted (so eavesdropping is prevented), but you lose server authentication — a man-in-the-middle attack could impersonate your broker and intercept all data. Use setInsecure() only for initial testing and never in production devices deployed in the field, especially in security-sensitive applications like smart locks, alarm systems, or financial IoT devices.

Build Secure IoT Projects with Zbotic

Get ESP32 modules, sensors, and all the hardware you need to build secure, production-ready IoT systems. Zbotic ships across India — Mumbai, Delhi, Bangalore, Hyderabad, Chennai, Pune and beyond.

Shop ESP32 & IoT Modules

Tags: ESP32 MQTT, ESP32 WiFi security, IoT security, MQTT broker, TLS SSL ESP32
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
ESP32 I2C Multiple Sensors: Sc...
blog esp32 i2c multiple sensors scan and read address guide 595573
blog esp32 ulp coprocessor wake sensor in deep sleep mode 595580
ESP32 ULP Coprocessor: Wake Se...

Related posts

Svg%3E
Read more

IoT Home Insurance Sensor Kit: Leak, Smoke, and Motion

April 1, 2026 0
Table of Contents IoT and Home Insurance Water Leak Detection Smoke and Fire Detection Motion and Intrusion Sensing Building the... Continue reading
Svg%3E
Read more

IoT Pet Tracker: GPS Collar with Geofencing Alerts

April 1, 2026 0
Table of Contents Introduction and Overview Hardware Components Required GPS Module Integration with ESP32 Cloud Platform Setup Real-Time Tracking Dashboard... Continue reading
Svg%3E
Read more

IoT Aquaponics Controller: Fish and Plant Automation

April 1, 2026 0
Table of Contents The Water Monitoring Challenge in India Sensor Technologies for Water Building the Sensor Node Data Transmission and... Continue reading
Svg%3E
Read more

IoT Composting Monitor: Temperature and Moisture Tracking

April 1, 2026 0
Table of Contents Why Temperature Monitoring Matters Sensor Selection Guide Hardware Assembly and Wiring Firmware Development Cloud Data Logging Alert... Continue reading
Svg%3E
Read more

IoT Beehive Monitor: Weight, Temperature, and Humidity

April 1, 2026 0
Table of Contents Why Monitor Beehives Weight Measurement System Temperature and Humidity Sensing Building the Monitor Data Analysis for Bee... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now