IoT Security: Connecting Your ESP8266 to Adafruit IO with SSL/TLS
The ESP8266 based Adafruit HUZZAH breakout and the Adafruit Feather HUZZAH are both popular options to use with Adafruit IO. Because ESP8266 SSL/TLS support is fairly new, most of our Adafruit IO examples use the insecure MQTT port 1883.
Why is this a problem? The MQTT protocol is an insecure protocol on it’s own. All data (including username & password) are sent in the clear, so SSL/TLS is required to protect any sensitive information.
What are SSL & TLS? Transport Layer Security (TLS) and its predecessor, Secure Sockets Layer (SSL), are cryptographic protocols that you use whenever you browse the internet. Have you ever noticed the lock symbol 🔒 in your browser’s URL bar? That lock symbol represents a secure connection between your browser & a web site over SSL/TLS. We use those same protocols to secure traffic between your ESP8266 and Adafruit IO.
We have added an example to the Adafruit_MQTT Arduino Library
that you can use to secure communication between your ESP8266 and Adafruit IO. Install or update the Adafruit MQTT Library to version 0.13.2
in the Arduino Library Manager, and open the
adafruitio_secure_esp8266
example to get started.
The main changes to the standard ESP8266 example are that WiFiClientSecure
is used in place of WiFiClient
, and port 8883
is used instead of MQTT port 1883
. The sketch
also checks the fingerprint for the io.adafruit.com
certificate using the verifyFingerprint
function.
A simplified summary of the changes can be seen below:
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 8883 // 8883 for MQTTS
// WiFiFlientSecure for SSL/TLS support
WiFiClientSecure client;
// io.adafruit.com SHA1 fingerprint
const char* fingerprint = "26 96 1C 2A 51 07 FD 15 80 96 93 AE F7 32 CE B9 0D 01 55 C4";
void verifyFingerprint() {
const char* host = AIO_SERVER;
Serial.print("Connecting to ");
Serial.println(host);
if (! client.connect(host, AIO_SERVERPORT)) {
Serial.println("Connection failed. Halting execution.");
while(1);
}
if (client.verify(fingerprint, host)) {
Serial.println("Connection secure.");
} else {
Serial.println("Connection insecure! Halting execution.");
while(1);
}
}