This article is a quick and simple introduction to HTTPS and SSL/TLS encryption with the ESP32 and ESP8266 NodeMCU board. We’ll take a look at some concepts and terms that you’ve probably heard before but you might not know exactly what they mean: HTTPS, SSL/TLS, certificates, asymmetric and symmetric key encryption, and more.
Table of Contents
Throughout this article, we’ll cover the following subjects:
- What is HTTPS?
- What is SSL/TLS?
- How does SSL/TLS encryption work?
- Communication over HTTPS
- SSL certificates
- Self-signed certificates
- ESP32: HTTPS requests (Arduino IDE)
- ESP32 HTTPS server (Arduino IDE)
- ESP8266: HTTPS requests (Arduino IDE)
- ESP8266 HTTPS server (Arduino IDE)
What is HTTPS?
HTTPS is the secure version of the HTTP protocol, hence the “S”, which stands for secure.
HTTP is a protocol to transfer data over the internet. When that data is encrypted with SSL/TLS, it’s called HTTPS.
To simplify, HTTPS is just the HTTP protocol but with encrypted data using SSL/TLS.
Why do you need HTTPS?
Using HTTPS ensures the following:
- Privacy: no one can spy on your requests and passwords because the messages are encrypted.
- Integrity: the message is not manipulated on its way to its destination (prevents men-in-the-middle) attacks.
- Identification: when using HTTPS, via SSL certificates, you ensure you are connected to the server you would expect.
What is SSL/TLS?
SSL stands for Secure Socket Layer and TLS stands for Transport Layer Security. These are two protocols used for secured encryption. SSL is currently deprecated. TLS 1.3 is currently the most recent protocol used for secure encryption on the web.
How does SSL/TLS encryption work?
There are two types of encryption algorithms: symmetric key algorithm and asymmetric key algorithm.
Symmetric Key Encryption
With a symmetric-key algorithm, the same key is used to encrypt and decrypt the messages. So, both the client and server need to have the same key.
The disadvantage of using a symmetric key algorithm is that keys are hard to share and you need to be careful how and with who you distribute the key.
Asymmetric Key Encryption
The SSL/TLS encryption uses asymmetric keys.
How does asymmetric key encryption work? Very briefly:
- You have two asymmetric keys: a public key and a private key.
- The public key and private key work together.
- The public key, as the name suggests, is visible to anyone.
- Only the private key can decrypt the message encrypted with the corresponding public key.
Public Key and Private Key
In summary, here’s how it works:
- The browser client tries to contact the server.
- The server sends the public key to the client (browser) via the server’s SSL certificate.
- The browser sends a message to the server encrypted with the public key.
- Only the ones with the private key (the server) can decipher the message.
Communication over HTTPS
How the communication between the server and client works over HTTPS? The following diagram shows a high-level overview of how it works.
- You, the client on your browser, try to connect with the server (1);
- The server sends back its certificate (2) so that the browser can check the authenticity of the server (3). The certificate contains the public key.
- If the certificate is valid, the client creates a new key (called session key) (4) that will be used later to encrypt communication between the client and server.
- The client encrypts the session key using the public key sent by the server (5).
- The server receives the session key encrypted with the public key and can decipher the message because only the server has access to the corresponding private key to decrypt the message (6);
- From now on, both the client and server have a secret key (that’s only known to them) that they can use to encrypt further communication (7) (symmetric key encryption).
SSL Certificates
SSL certificates are issued by legitimate Certificate Authorities. One of the most known is LetsEncrypt. Certificate Authorities also confirm the identity of the certificate owner and provide proof that the certificate is valid.
When a Certificate Authority issues a certificate, it signs the certificate with its root certificate. This root certificate should be on the database of trusted certificates.
Your browser then checks if the certificate is valid (if it was signed with a root certificate on the database of trusted root certificates) and displays a green lock icon on the browser bar if it is.
Self-signed Certificates
You can self-sign your certificates. These provide the same level of encryption as one generated by an authority, and these are free. However, all browsers will check if the certificate is issued by a trusted Certificate Authority. So, you’ll be warned by your browser that the site you’re visiting is not safe because it doesn’t trust the certificate and so, can’t identify its owner.
The web browser will display a warning sign and the HTTPS letters in red. This means the website has a certificate, but the certificate is unverified (like self-signed certificates) or out of date. This means that the connection between you and the server is encrypted, but no one can guarantee that the domain really belongs to the company indicated on the site.
Self-signed certificates are fine to use on your DIY and IoT projects, intranets, like your local network, or inside a company’s network. However, if you’re creating a project for a company that will be accessed by clients outside the company network, like a public website, it’s best to use a certificate from a Certificate Authority.
SSL certificates have an expiry date. So, if you’re using an ESP32 to connect to a website via HTTPS, you should keep in mind that you’ll need to update the code with the new website’s certificate in the future.
If you’re still confused about all of these new terms, we recommend taking a look at the following website that explains in a fun way how everything works: https://howhttps.works/.
ESP32: HTTPS Requests (Arduino IDE)
If you’re familiar with HTTP requests with the ESP32 “migrating” to HTTPS is very straightforward.
If you’re using the WiFiClient library, you just need to make the following changes:
- Use WiFiClientSecure.h library instead of WiFiClient.h
- Use port 443 instead of port 80
- Change the host URL to https instead of http
With this, you ensure that your communication is encrypted using TLS.
An additional security step is to check the server certificate (the certificate of the website you want to connect to). You can skip this step while testing and prototyping. The communication will be encrypted, but you won’t be sure of the integrity of the server you are trying to communicate with.
You can also find examples using HTTPS with the HTTPClient library.
If you want to start working on your HTTPS requests right away, take a look at the examples provided in the ESP32 package for the Arduino core.
- WiFiClientSecure example: File > Examples > ESP32 > WFiClientSecure > WiFiClientSecure
- HTTPClient with HTTPS example: File > Examples > ESP32 > BasicHttpsClient > BasicHttpsClient
ESP32 HTTPS Server (Arduino IDE)
At the moment, there are not many examples of building an HTTPS web server with the ESP32 using the Arduino core. Unfortunately, the AsyncWebServer library that we use in most of our projects, doesn’t fully support HTTPS at the moment.
Nevertheless, there is another library that provides easy methods to build an ESP32 HTTPS web server, including an example that generates certificates on the fly. Here’s a link to the library: esp32_https_server library.
If you’re familiar with ESP-IDF, you can take a look at the documentation on the following link:
ESP8266 HTTPS Requests (Arduino IDE)
There are several examples that show how to make HTTPS requests with the ESP8266. You can check the examples available in your Arduino IDE. Make sure you have the latest version of the ESP8266 boards installed to make sure you have access to the latest version of the examples and that these will work.
To update the ESP8266 boards’ installation, you just need to go to Tools > Boards > Boards Manager, search for ESP8266, and install the latest version.
Then, you’ll have access to the examples’ latest version. You can check the following examples:
- Basic HTTPS Client using the ESP8266HTTPClient library: File > Examples > ESP8266HTTPClient > BasicHttpsClient
- Basic HTTPS Client using WiFiClientSecure library: File > Examples > ESP8266WiFi > HTTPSRequest
You’ll need to update the certificates and fingerprints to make the examples work. If you can’t make the examples work, don’t worry, we’ll publish some tutorials with examples and instructions soon.
ESP8266 HTTPS Server (Arduino IDE)
The ESP8266 is not optimized for SSL cryptography, so running an HTTPS Server on the ESP8266 is very demanding. You need to set the clock frequency to 160MHz and even so, you might get unexpected resets on the board.
For an ESP8266 HTTPS web server, you can take a look at an example using the ESP8266WebServer library on the following link:
Wrapping Up
In this tutorial, we’ve taken a look at the HTTPS protocol, SSL/TLS encryption, and SSL certificates. I’m far from being an expert in these subjects, so if anything doesn’t sound right in this article, please let me know in the comments below.
We’ve also taken a quick look at possible ways to secure your ESP32/ESP8266 IoT projects: how to make HTTPS requests and how to set the ESP32/ESP8266 as an HTTPS server with a certificate. We’ll create more tutorials with practical examples about these subjects in the upcoming weeks, so stay tuned.
If you have any examples of HTTPS servers with the ESP32 or are familiar with any other libraries to build an HTTPS server, please share them in the comments below.
Thanks for reading.
Love your website. Please keep up the great work!
Thanks 😀
Hi.
I would like to see an example with the async web server library, or is this library completely abandoned. I had some problems with espressif’s Esp32 s3 chip until I found these links
https://github.com/esphome/ESPAsyncWebServer
https://github.com/esphome/AsyncTCP
Hi.
I don’t think HTTPS is fully implemented on those libraries yet.
At least, from what I searched I couldn’t find any complete example about that.
Regards,
Sara
You do good work, well explained, not a little bit, always in detail. I like it very much, Merry Christmas from germany
Thanks.
Merry Christmas from Portugal!
Just Finished reading THE RANSOMWARE HUNTIBG TEAM ;this tutorial was very timely
Thanks Sara
Sara Sorry ” HUNTIBG” should be ” HUNTING ” – fat fingers
Hi.. First, thank you very much because your website helps a lot.
I built a captive port project, My project requires users to read the terms and conditions before continuing. I have managed to make anyone connected to my esp wifi be redirected or display a captive portal Even when he starts opening an HTTP website, the problem is that if someone opens an HTTPS website then their browser shows an error because there is no connection or something.
Is there a way when they open https will be redirected to the captive portal page? In other program languages I can create “if https is requested by the client, then ignore it, after sending captive portal” or if https request is requested then remove the “S” on “https”.
I’m just beginning to understand Arduino’s language or its commands, and is that possible?
Thanks 😀
Muchas gracias Sara muy oportuno. Saludos cordiales desde Colombia.
Very clear article.Thanks
Is it possible to amend th ecode on the ESP8266 BME webserver sketch you have to HTTPS? Or would you haveto write the whole page of code differently?
Hi.
Unfortunately, at the moment there isn’t TLS support on the AsyncWebServer library, you would need to use a different library and rewrite the code.
Regards,
Sara
Oh, Sara.Thanks a lot! I was looking for https explanation for a while.
Merry Christmas from Brazil.
Thank you.
Have a great holiday season.
Regards,
Sara
Do you recommend any examples using HTTPS with the HTTPClient library?
Hi.
We have this example: https://randomnerdtutorials.com/esp32-https-requests/
The other website you mentioned, copies all our content and changes only some words to make it seem that they have original content. almost all their tutorials are a copy of ours. Even the theme and structure of their website is copied from ours. So, it would be nice if you check our website first, before checking theirs.
Regards,
Sara
Thanks for approaching the subject of HTTPS server. Unfortunately there isn’t many options available yet.
I’m currently trying to use code from esp-idf sample showcasing secured websockets.
My project is using arduino-esp32 which from my current understanding depends on esp-idf.
In the code I copied, the header esp_https_server.h is included, but at compilation it seems to look at non secure implementation as it complains about missing declaration.
I wonder if there any compile flags required to build that esp-idf sample and how it could be done from an arduino-esp32 project
Do you have any experience in compiling code from esp-idf from arduino-esp32 project and maybe provide some advice?
Thanks,
Unfrtunately this entire webserver is no longer really useful. It is slow and drops SSL connections and the maintainer pretty much dropped the issue in mid-2022.
It semi-sorta works, but the SSl library is depricated and requires a manual edit to point at a different hash library.
Not your fault at all, but we need a better solution that really works!
Hi.
What library in particular are you referring to?
Regards,
Sara
Both incarnations of ESP_HTTPS_SERVER (and ESPWebServerSecure), originally by Frank Hessel. They basically fail at the initial connect then retry until success, it takes 3 – 5 seconds. You can see a discussion of this on GitHub. If you need a secure webserver, with responses times in the under one second range (like you can easily get with the non secure ones), this just doesn’t work. I did some time checks and it’s the SSL handshake that takes all the time. The page writes, after the TLS tunnel is established take 1 – 3 milliseconds on a local network.
To explain my purpose, I have a device that I want to be controlled in relatively real time from anything, Andriod phone or tablet, iPhone or tablet, or any computer with a web-browser. If I put the server on the ESP32 everything can access it (which going back to the birth of the internet, how Tim Berners-Lee envisioned it, not with an app for every function on every platform as we have now).
But so far, I have not been able to get a reasonable HTTPS server running on an ESP32. Mostly is seem to be a problem with the TLS libraries.
If there is a better, faster library, I’d love to know about it!
Thanks!
Steve
Hi guys, In most of my projects I use a generic ESP8266. If I need more i/o pin I go to the ESP32. I mostly use them in conjunction with mqtt and Node Red dashboard, and sometimesas a stand alone server. I’m just wondering if there has been any progress on a securing these, particularly in a server mode
Hi Sara, this is a very nice material, congratulations!
I am using ESP8266 via AT Commands connecting it to a host controller. I am able to open a TCP connection and send my data to a MQTT broker, it is working fine.
I would like to change it to a secure TCP connection with TLS encryption. The same MQTT broker offers both secure and insecure connection, I just need to change the port.
But, I do not know how to start it!
How to get the certificate, where to flash it in the ESP8266, and so on… ?
Please, any idea or material to recommend me?
Muito obrigado,
Iaran