Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ESP8266 Secure MQTT Connection with Client Certificate Authentication
#include <FS.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <time.h>
// Insert your FQDN of your MQTT Broker
#define MQTT_SERVER "mqtt.srvx1.local"
const char* mqtt_server = MQTT_SERVER;
// WiFi Credentials
const char* ssid = "insert_coin";
const char* password = "supersecretwifipassword";
// Static IP configuration
#define IPSET_STATIC { 10, 10, 10, 13 }
#define IPSET_GATEWAY { 10, 10, 10, 254 }
#define IPSET_SUBNET { 255, 255, 255, 0 }
#define IPSET_DNS { 10, 10, 10, 254 }
byte ip_static[] = IPSET_STATIC;
byte ip_gateway[] = IPSET_GATEWAY;
byte ip_subnet[] = IPSET_SUBNET;
byte ip_dns[] = IPSET_DNS;
// Fingerprint of the broker CA
// openssl x509 -in mqttserver.crt -sha1 -noout -fingerprint
const char* fingerprint = "28:7C:0E:AC:E1:B9:00:9B:DB:4B:BA:19:0A:3D:4A:B5:F6:AA:4D:A6";
// Topic
char* topic = "test";
String clientName;
long lastReconnectAttempt = 0;
long lastMsg = 0;
int test_para = 2000;
unsigned long startMills;
WiFiClientSecure wifiClient;
PubSubClient client(mqtt_server, 8883, wifiClient);
void verifytls() {
// Use WiFiClientSecure class to create TLS connection
Serial.print("connecting to ");
Serial.println(mqtt_server);
if (!wifiClient.connect(mqtt_server, 8883)) {
Serial.println("connection failed");
return;
}
if (wifiClient.verify(fingerprint, mqtt_server)) {
Serial.println("certificate matches");
} else {
Serial.println("certificate doesn't match");
}
}
// Load Certificates
void loadcerts() {
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
// Load client certificate file from SPIFFS
File cert = SPIFFS.open("/esp.der", "r"); //replace esp.der with your uploaded file name
if (!cert) {
Serial.println("Failed to open cert file");
}
else
Serial.println("Success to open cert file");
delay(1000);
// Set client certificate
if (wifiClient.loadCertificate(cert))
Serial.println("cert loaded");
else
Serial.println("cert not loaded");
// Load client private key file from SPIFFS
File private_key = SPIFFS.open("/espkey.der", "r"); //replace espkey.der with your uploaded file name
if (!private_key) {
Serial.println("Failed to open private cert file");
}
else
Serial.println("Success to open private cert file");
delay(1000);
// Set client private key
if (wifiClient.loadPrivateKey(private_key))
Serial.println("private key loaded");
else
Serial.println("private key not loaded");
// Load CA file from SPIFFS
File ca = SPIFFS.open("/ca.der", "r"); //replace ca.der with your uploaded file name
if (!ca) {
Serial.println("Failed to open ca ");
}
else
Serial.println("Success to open ca");
delay(1000);
// Set server CA file
if(wifiClient.loadCACert(ca))
Serial.println("ca loaded");
else
Serial.println("ca failed");
}
void getTime(){
// Synchronize time useing SNTP. This is necessary to verify that
// the TLS certificates offered by the server are currently valid.
Serial.print("Setting time using SNTP");
configTime(8 * 3600, 0, "de.pool.ntp.org");
time_t now = time(nullptr);
while (now < 1000) {
delay(500);
Serial.print(".");
now = time(nullptr);
}
Serial.println("");
struct tm timeinfo;
gmtime_r(&now, &timeinfo);
Serial.print("Current time: ");
Serial.print(asctime(&timeinfo));
}
boolean reconnect()
{
if (!client.connected()) {
if (client.connect((char*) clientName.c_str())) {
Serial.println("===> mqtt connected");
} else {
Serial.print("---> mqtt failed, rc=");
Serial.println(client.state());
}
}
return client.connected();
}
void wifi_connect()
{
if (WiFi.status() != WL_CONNECTED) {
// WIFI
Serial.println();
Serial.print("===> WIFI ---> Connecting to ");
Serial.println(ssid);
delay(10);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
WiFi.config(IPAddress(ip_static), IPAddress(ip_gateway), IPAddress(ip_subnet), IPAddress(ip_dns));
int Attempt = 0;
while (WiFi.status() != WL_CONNECTED) {
Serial.print(". ");
Serial.print(Attempt);
delay(100);
Attempt++;
if (Attempt == 150)
{
Serial.println();
Serial.println("-----> Could not connect to WIFI");
ESP.restart();
delay(200);
}
}
Serial.println();
Serial.print("===> WiFi connected");
Serial.print(" ------> IP address: ");
Serial.println(WiFi.localIP());
}
}
void setup()
{
Serial.begin(115200);
startMills = millis();
wifi_connect();
delay(500);
getTime();
delay(500);
loadcerts();
delay(200);
clientName += "esp8266-";
uint8_t mac[6];
WiFi.macAddress(mac);
clientName += macToStr(mac);
clientName += "-";
clientName += String(micros() & 0xff, 16);
}
void loop()
{
if (WiFi.status() == WL_CONNECTED) {
if (!client.connected()) {
long now = millis();
if (now - lastReconnectAttempt > 2000) {
lastReconnectAttempt = now;
if (reconnect()) {
lastReconnectAttempt = 0;
}
}
} else {
long now = millis();
if (now - lastMsg > test_para) {
lastMsg = now;
String payload = "{\"startMills\":";
payload += (millis() - startMills);
payload += "}";
sendmqttMsg(topic, payload);
}
client.loop();
}
} else {
wifi_connect();
}
}
void sendmqttMsg(char* topictosend, String payload)
{
if (client.connected()) {
Serial.print("Sending payload: ");
Serial.print(payload);
unsigned int msg_length = payload.length();
Serial.print(" length: ");
Serial.println(msg_length);
byte* p = (byte*)malloc(msg_length);
memcpy(p, (char*) payload.c_str(), msg_length);
if ( client.publish(topictosend, p, msg_length)) {
Serial.println("Publish ok");
free(p);
//return 1;
} else {
Serial.println("Publish failed");
free(p);
//return 0;
}
}
}
String macToStr(const uint8_t* mac)
{
String result;
for (int i = 0; i < 6; ++i) {
result += String(mac[i], 16);
if (i < 5)
result += ':';
}
return result;
}
@KevinHunter12

This comment has been minimized.

Copy link

KevinHunter12 commented Jul 24, 2018

Exactly what Ive been searching for but i cant get it to work :( (issue on my side).
The IoT platform im trying to connect too gives me a client certificate but where do i get the private key and ca file from ?? I know nothing about certificate security :(

Thanks
Kev

@m0ot

This comment has been minimized.

Copy link

m0ot commented Oct 18, 2018

Hi there,
can you please upload the whole source code, I mean with the libraries ?
thanks,

@sw-tt-chandershekharsuthar

This comment has been minimized.

Copy link

sw-tt-chandershekharsuthar commented Jan 31, 2019

hey
I'm trying to connect with broker with this( by CA certificate ) way but getting the same " Attempting MQTT connection...failed, rc=-2 try again in 5 seconds "
I'm using CA, client certificate, client private key all file which you ask in .der
with fingerprint of CA file but the connection is still open.

@JosephCottingham

This comment has been minimized.

Copy link

JosephCottingham commented Jun 26, 2019

Please send aid by uploading your entire directory, I am having problems pulling the files. My job and therefore my life depends on it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.