Access Controllers with ESP32, Secure MQTT, and mTLS Encryption
Learn how to design a physical access control system using ESP32 microcontrollers, lightweight MQTT communication, and mTLS security to shield your network.
Summary
- mTLS encryption ensures mutual authentication between the ESP32 and the server, preventing unauthorized rogue devices from joining the network.
- The MQTT protocol operates with extremely low bandwidth consumption, making it ideal for industrial and building environments with unstable links.
- Local validation of badges and passwords ensures doors can still open even during temporary internet connection dropouts.
- Securely storing digital certificates in the microcontroller flash memory protects cryptographic keys against physical extraction.
- The distributed architecture eliminates single points of failure, allowing each controller to operate autonomously.
The Challenge of Security in Smart Gateways
When designing gate automation and turnstile systems, response speed is usually the primary concern. However, connecting physical devices directly to corporate networks or the cloud without proper precautions opens severe security vulnerabilities. An intruder with physical access to a wall-mounted badge reader could theoretically intercept wiring or extract the microcontroller to clone network traffic. In practice, this means an access control system must be as heavily fortified as a banking server.
To solve this dilemma in Internet of Things (IoT) projects—the network of everyday objects connected to the internet—we must replace open connections with robust protocols. The ESP32 microcontroller emerges as an excellent choice by combining low cost, built-in Wi-Fi connectivity, and sufficient processing power to handle heavy cryptography. Combined with the MQTT protocol, which acts as a lightweight message broker for machine-to-machine updates, the ESP32 can send and receive commands instantly without overloading the network.
Understanding the Architecture with MQTT and mTLS
MQTT operates through a central server called a broker, which organizes and distributes messages sent by devices. Imagine the broker as a building telephone switchboard: access readers call in to report a card swipe, and the switchboard decides whether to unlock the door. The major flaw is that, by default, MQTT transmits data in plain text or basic encryption without rigorously verifying who is on the other end. This is where mTLS, or Mutual Transport Layer Security, comes into play.
In practice, mTLS mandates that both the server and the ESP32 present valid digital certificates to each other before exchanging a single word. The server trusts the ESP32 because it holds a unique secret key burned into its memory, and the ESP32 trusts the server because it holds the matching root certificate. If a malicious device tries to impersonate a legitimate controller, the server detects the missing valid credential and immediately terminates the connection, blocking any door-opening commands.
Preparing the Environment and Configuring Certificates
Before writing the firmware code that runs on the ESP32, we must generate the cryptographic keys that establish equipment identity. This process involves creating a private certificate authority, acting as the notary office for our private system. In your computer terminal, you will need to generate a root certificate, followed by specific certificates for the MQTT server and each ESP32 board deployed at the doors.
- Generate the certificate authority private key by running openssl genrsa -out ca.key 2048 in your terminal.
- Create the self-signed authority certificate using openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt.
- Generate the client key and signing request for the ESP32 using openssl req -new -nodes -out client.csr -keyout client.key.
With these files generated, you will need to embed them directly into the ESP32 source code or store them in a dedicated flash memory partition called SPIFFS. Hardcoding certificates simplifies initial testing but requires extreme caution to avoid leaking private keys into public repositories. Each board must receive its own distinct key and certificate, ensuring that compromising a single turnstile does not breach the security of the entire building.
Implementing Firmware on the ESP32
The code running on the microcontroller must simultaneously manage three fundamental tasks: maintaining a stable Wi-Fi connection, listening to RFID reader or keypad events, and keeping the encrypted MQTT channel active. To achieve this, we use the PubSubClient library alongside the native WiFiClientSecure class from the Arduino ESP32 development environment. The connection function must validate certificate memory pointers before attempting communication with the broker.
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
const char* ssid = "YourWiFiNetwork";
const char* password = "YourWiFiPassword";
const char* mqtt_server = "192.168.1.100";
WiFiClientSecure espClient;
PubSubClient client(espClient);
const char* root_ca = "-----BEGIN CERTIFICATE-----
...";
const char* certificate = "-----BEGIN CERTIFICATE-----
...";
const char* private_key = "-----BEGIN PRIVATE KEY-----
...";
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
void setup() {
Serial.begin(115200);
setup_wifi();
espClient.setCACert(root_ca);
espClient.setCertificate(certificate);
espClient.setPrivateKey(private_key);
client.setServer(mqtt_server, 8883);
}
void loop() {
if (!client.connected()) {
// Secure reconnection routine
}
client.loop();
}In the code snippet above, we configure port 8883, the universal standard for encrypted MQTT traffic over TLS. Should a power outage or radio signal loss occur, the ESP32 must attempt cyclical reconnection routines without freezing local card reads. It is crucial to implement local fallback logic that permits unlocking the door for registered residents even when the core network is offline.
Local Validation and Operational Resilience
A corporate access control system cannot stop functioning simply because a Wi-Fi router rebooted or the central server became overwhelmed. To mitigate this issue, the best engineering practice is to store a cached list of valid credentials directly in the ESP32 non-volatile memory. When a badge is scanned, the microcontroller first checks if the user exists in its internal emergency permissions list.
If the local list approves entry, the relay triggering the electromagnetic lock fires instantly, and an offline audit log is queued for delivery as soon as MQTT broker connectivity is restored. In practice, this ensures a seamless user experience and prevents annoying queues at building entrances. Synchronization of this local database happens in the background using dedicated MQTT topics subscribed exclusively by that specific controller.
Final Considerations and System Maintenance
Implementing an ESP32-based access control controller with MQTT and mTLS raises security standards for corporate and residential projects, proving that affordable hardware can deliver industrial-grade robustness. The secret to operational success lies in disciplined digital certificate management and the creation of resilient routines for network failures. By adopting mutual encryption and hybrid validation, you protect client assets and ensure continuous, auditable operation.