In this guide, you’ll learn how to make HTTPS requests with the ESP8266 NodeMCU board. We’ll introduce you to some HTTPS fundamental concepts and provide several examples: HTTPS requests without certificate, with fingerprint and with certificate.
We have a similar tutorial for the ESP32 board:
Table of Contents
Throughout this article, we’ll cover the following subjects:
- What is HTTPS?
- SSL/TLS Certificates
- Getting a Server’s Certificate using Google Chrome
- HTTPS Requests with the ESP8266
Introduction
To understand how to make HTTPS requests with the ESP8266, it’s better to be familiar with some fundamental concepts that we’ll explain next. We also recommend taking a look at the following article:
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 with the ESP8266?
Using HTTPS ensures the following:
1) Encryption: all traffic between the ESP8266 and a server will be encryptedâno one can spy on your requests and passwords, they will only see gibberish.
When using the ESP8266 libraries to make HTTPS requests, they take care of encryption and decryption of the messages.
2) Server trust (identification): when using HTTPS, via TLS/SSL certificates, you ensure you are connected to the server you would expectâthis means, you always know to who you are connected to.
To make sure we are connected to the right server, we need to check the server certificate on the ESP8266 or the server fingerprint. This means we need to download the server certificate or fingerprint and hard code it on our sketch so that we can check if we’re actually connected to the server we are expecting.
TLS/SSL Certificates
SSL certificates are issued by legitimate Certificate Authorities. One of the most known is LetsEncrypt. Certificate Authorities confirm the identity of the certificate owner and provide proof that the certificate is valid. The certificate also contains the server’s public key for asymmetrically encrypted communication with a client.
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 called a root store. Your browser and the operating system contain a database of root certificates that they can trust (root store). The following screenshot shows some of the trusted root certificates.
So, when you connect to a website using your browser, it checks if its certificate was signed by a root certificate that belongs to its root store. New root certificates are added or deleted to the root store with each browser update.
When you’re using an ESP8266, you need to upload the certificates that you trust to your board. Usually, you’ll add only the certificate for the server you’ll want to connect to.
But, it’s also possible to upload a root store to your board to have more options, and don’t have to worry about searching for a specific website’s certificate.
Certificate Chain
An SSL certificate is part of an SSL certificate chain. What is a certificate chain?
A certificate chain includes the following:
- root certificate (from a Certificate Authority);
- one or more intermediate certificates;
- the server certificate.
The server certificate is what makes your browser show a secure padlock icon when you visit a website. It means the server has a valid SSL/TLS certificate and all the connections with the website are encrypted. A valid SSL/TLS certificate is a certificate trusted by your browser. What makes it trustable?
As we’ve mentioned previously, SSL/TLS certificates are issued by Certificate Authorities. However, these authorities don’t issue certificates directly to websites. They use intermediates that will issue the server certificate (Certificate Authority > intermediate certificate > server certificate). The following screenshot shows an example for the Github website. You can see the certificate hierarchy highlighted with a red rectangle.
Your browser checks this certificate chain until it finds the root certificate. If that certificate is in the browser’s root store, then it considers the certificate to be valid. In this case, the DigiCert Global Root CA is in the browser’s root store. So, it will display the “secure” icon on the browser bar.
The following diagram shows a high-level overview of how it works.
In summary:
- root certificate: it’s a self-signed certificate issued by a Certificate Authority. The private key of this certificate is used to sign the next certificate in the hierarchy of certificates. Root certificates are loaded in the trust stores of browsers and operating systems.
- intermediate certificate: it’s signed by the private key of the root certificate. The public key of the intermediate certificate is the one that signs the server certificate. There can be more than one intermediate certificate.
- server certificate: this certificate is issued to a specific domain name on a server. It’s signed by the intermediate certificate public key. If it is valid (trustable certificate chain), the browser displays a secure padlock badge on the search bar next to the website domain.
With the ESP8266, to check the validity of a server, you can load any of those certificates: root, intermediate, or server certificate. Instead of the certificate, you can also check the certificate fingerprint. The fingerprint is a hash of the certificate (a unique identifier of the certificate generated from the certificate information).
Certificates Expiration Date
SSL/TLS certificates have an expiry date. You can check on a browser the expiry date of the certificate for a particular server. The server’s certificate usually has a short-term validity and the fingerprint validity is even shorter.
So, if you want to use them in your ESP8266 projects, you’ll need to update your code quite frequently. If you want your code to run for years without worrying, you can use the website’s root certificate, which usually has a validity of five to ten years or more. However, using the fingerprint might be useful for testing purposes or might be a good option depending on the application.
Getting a Server’s Certificate
There are different ways to get the server’s certificate. One of the easiest ways is to download the certificate directly from your browser. You can also use OpenSSL and get all the certificate information you need using the command line (we won’t cover this method in this tutorial).
In this section, you’ll learn how to get the server’s certificate. We’ll generally use the root certificate, but you can use any of the other certificates on the certificate chainâyou just need to be aware of the certificate expiry date.
Getting a Server’s Certificate using Google Chrome
In this section, we’ll show you how to get the certificate for a server using Google Chrome (that’s the web browser we use more often). Instructions for other web browsers should be similar.
The examples we’ll use later show how to make an HTTPS request to the howmyssl.com website. So, for demonstration purposes, we’ll show you how to get its root certificate. It is similar for other websites.
How to Get Websites’s Certificate using Google Chrome?
- Go to the website that you want to get the certificate for.
- Click on the padlock icon and then click on Show connection details.
- Then, click on Show certificate.
- A new window will open with all the information about the website’s certificate. Click on the Details tab, make sure you select the root certificate (that’s what we’re looking for in this example), then click on Export…
- Select a place on your computer to save the certificate. Save it on the default format: Base64-encoded ASCII, single certificate (*.pem, .crt). And that’s it.
You can double-click on the certificate file to check its details, including the expiration date.
Open the certificate using Notepad or other similar software. You should get something similar as shown below.
How to Get a Website’s Fingerprint using Google Chrome?
Getting a website’s certificate fingerprint is straightforward. Follow the next instructions:
- Go to the website that you want to get the fingerprint.
- Click on the padlock icon and then click on Show connection details.
- Then, click on Show certificate.
- A new window will open with all the information about the website’s certificate, including the fingerprints. For the ESP8266 examples, you’ll use the SHA-1 fingerprint.
HTTPS Requests with the ESP8266 NodeMCU
Now that you know all the major important aspects of certificates and how to get a server’s certificate, let’s finally take a look at how to make HTTPS requests with the ESP8266 using the Arduino core. We’ll cover different methods: without a certificate, with the website fingerprint, and with the server’s root certificate.
You can find different examples showing how to make HTTPS requests with the ESP8266 in the Arduino IDE examples section.
- Basic HTTPS Client (ESP8266HTTPClient library): File > Examples > ESP8266HTTPClient > BasicHTTPSClient
- Basic HTTPS Client (WiFiClientSecure library): File > Examples > ESP8266WiFi > HTTPSRequest
Youâll need to update the certificates and fingerprints to make the examples work. We created several examples based on those. All examples presented make a request to the www.howsmyssl.com/a/check website. It returns some information regarding how secure the HTTPS connection is. Let’s take a look at them.
ESP8266 NodeMCU HTTPS Requests – No Certificate
You can make HTTPS requests with the ESP8266 without a certificate and without a fingerprint. The connection will be encrypted, but you’ll skip the SSL server certificate verification. This means that you won’t be sure if the server you’re connected to is really who it claims to be. This situation is useful for testing purposes or to make HTTPS requests to local servers inside your network.
The following code was based on the BasicHttpsClient example.
To test the code, simply insert your network credentials and upload the code to your board.
/*
Complete project details: https://RandomNerdTutorials.com/esp8266-nodemcu-https-requests/
Based on the BasicHTTPSClient.ino Created on: 20.08.2018 (ESP8266 examples)
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
void setup() {
Serial.begin(115200);
//Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
//Connect to Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
}
void loop() {
// wait for WiFi connection
if ((WiFi.status() == WL_CONNECTED)) {
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
// Ignore SSL certificate validation
client->setInsecure();
//create an HTTPClient instance
HTTPClient https;
//Initializing an HTTPS communication using the secure client
Serial.print("[HTTPS] begin...\n");
if (https.begin(*client, "https://www.howsmyssl.com/a/check")) { // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
int httpCode = https.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
https.end();
} else {
Serial.printf("[HTTPS] Unable to connect\n");
}
}
Serial.println();
Serial.println("Waiting 2min before the next round...");
delay(120000);
}
How does the Code Work?
First, you need to include the required libraries. You need the WiFiClientSecureBearSSL library to make HTTPS requests.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
Insert your network credentials in the following lines.
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
In the setup(), initialize the Serial Monitor and connect the board to your Wi-Fi network.
void setup() {
Serial.begin(115200);
// Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
//Connect to Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
The following line creates a new WiFiClientSecure instance called client.
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
In case you don’t want to verify the server certificate, use the setInsecure() method on the client.
// Ignore SSL certificate validation
client->setInsecure();
Create an HTTPClient instance called https.
//create an HTTPClient instance
HTTPClient https;
Initialize the https client on the host specified using the begin() method. In this case, we’re making a request on the following URL: https://www.howsmyssl.com/a/check.
if (https.begin(*client, "https://www.howsmyssl.com/a/check")) { // HTTPS
Get the server response code.
int httpCode = https.GET();
If the response code is a positive number, it means the connection was established successfully, so we can read the response payload using the getString() method on the https object. Then, we can print the payload in the Serial Monitor. In a practical application, you can do whatever task you need with the ESP8266 depending on the received payload.
if (https.begin(*client, "https://www.howsmyssl.com/a/check")) { // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
int httpCode = https.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload);
}
If the response code is a negative number, it means we have an error. We’ll print the error code.
else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
Finally, close the HTTPS connection using the end() method:
https.end();
This specific example makes a request every two minutes. You should change it depending on your project requirements.
Serial.println("Waiting 2min before the next round...");
delay(120000);
Demonstration
After uploading the code, open the Serial Monitor at a baud rate of 115200. Press the on-board RST button to start running the newly uploaded code.
You should get something similar as shown in the picture below.
You get the response code 200, which means everything is fine with the request.
If you scroll to the right, you’ll get the result of how secure the connection is. You should get a “Probably Okay”.
Your connection is still encrypted, but with this example, it will skip SSL verification.
ESP8266 NodeMCU HTTPS Requests – Fingerprint
You can make HTTPS requests with the ESP8266, and check the server authenticity using the server fingerprint. One of the biggest downsides of using a fingerprint is that its validity is usually pretty short. So, you’ll need to update your sketch quite often.
Here’s an example using server verification with the fingerprint. This example is based on the BasicHttpsClient example. Because the fingerprint changes quite often, you may need to modify the code with the website’s current fingerprintâcheck this section to learn how to get the fingerprint.
/*
Complete project details: https://RandomNerdTutorials.com/esp8266-nodemcu-https-requests/
Based on the BasicHTTPSClient.ino Created on: 20.08.2018 (ESP8266 examples)
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Fingerprint (might need to be updated)
const uint8_t fingerprint[20] = {0x76, 0x99, 0x2e, 0x6f, 0x04, 0xf4, 0xad, 0x19, 0xba, 0x54, 0xf5, 0x92, 0x50, 0x51, 0x56, 0x2b, 0x86, 0x8b, 0x5a, 0x92};
void setup() {
Serial.begin(115200);
//Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
//Connect to Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
}
void loop() {
// wait for WiFi connection
if ((WiFi.status() == WL_CONNECTED)) {
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setFingerprint(fingerprint);
// Or, if you happy to ignore the SSL certificate, then use the following line instead:
// client->setInsecure();
HTTPClient https;
Serial.print("[HTTPS] begin...\n");
if (https.begin(*client, "https://www.howsmyssl.com/a/check")) { // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
int httpCode = https.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
https.end();
} else {
Serial.printf("[HTTPS] Unable to connect\n");
}
}
Serial.println();
Serial.println("Waiting 2min before the next round...");
delay(120000);
}
How does the Code Work?
The code in this example is very similar to the previous one but adds the necessary lines to check the server fingerprint. We’ll just take a quick look at the lines relevant for this example. For a more detailed explanation, check the previous example.
First, you need to include the required libraries. You need the WiFiClientSecureBearSSL library to make HTTPS requests.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
Insert your network credentials in the following lines:
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Insert the server fingerprint in the following line:
// Fingerprint for demo URL (might need to be updated)
const uint8_t fingerprint[20] = {0x76, 0x99, 0x2e, 0x6f, 0x04, 0xf4, 0xad, 0x19, 0xba, 0x54, 0xf5, 0x92, 0x50, 0x51, 0x56, 0x2b, 0x86, 0x8b, 0x5a, 0x92};
In a previous section, we’ve seen that the fingerprint for the URL we’ll make the request is:
76 99 2E 6F 04 F4 AD 19 BA 54 F5 92 50 51 56 2B 86 8B 5A 92
So, you must insert it in your code like this:
const uint8_t fingerprint[20] = {0x76, 0x99, 0x2e, 0x6f, 0x04, 0xf4, 0xad, 0x19, 0xba, 0x54, 0xf5, 0x92, 0x50, 0x51, 0x56, 0x2b, 0x86, 0x8b, 0x5a, 0x92};
Because the fingerprint changes frequently, you may need to double-check the current fingerprint. If you’re making a request on a different URL, you need to get its fingerprint as described previously.
You need to create a WiFiClientSecure instance called client.
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
To set the server fingerprint, use the setFingerpirnt() method on the client and pass the fingerprint as an argument:
client->setFingerprint(fingerprint);
Create an HTTPClient instance called https.
//create an HTTPClient instance
HTTPClient https;
Initialize the https client on the host specified using the begin() method. In this case, we’re making a request on the following URL: https://www.howsmyssl.com/a/check.
if (https.begin(*client, "https://www.howsmyssl.com/a/check")) { // HTTPS
Then, you just need to handle the server response. A response code of 200 means everything went as expected. A response code with a negative number means something went wrong with the request.
int httpCode = https.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
Demonstration
After uploading the code, open the Serial Monitor at a baud rate of 115200. Press the on-board RST button to start running the newly uploaded code.
You should get something similar as shown in the picture below (exactly like in the previous example).
You get the response code 200, which means everything is fine with the request.
If you scroll to the right, you’ll get the result of how secure the connection is. You should get a “Probably Okay”.
Your connection is encrypted and you verified the authenticity of the server using the server fingerprint.
ESP8266 NodeMCU HTTPS Requests – Root Certificate
In this section, we’ll show you an example of an HTTPS request using the server root certificate.
Using the server root certificate is a great option because you verify the server SSL certificate, and thus you guarantee you’re communicating with the right server. Additionally, the root certificate is usually valid for more than five years, which means you don’t need to constantly update your ESP8266 sketch (unlike the fingerprint method).
We’re providing an example based on the ESP8266_HTTPSRequest example, which you can find in your Arduino IDE: File > Examples > ESP8266WiFi > HTTPSRequest.
/*
Complete project details: https://RandomNerdTutorials.com/esp8266-nodemcu-https-requests/
Based on the example created by Ivan Grokhotkov, 2015 (File > Examples > ESP8266WiFi > HTTPSRequests)
*/
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266HTTPClient.h>
// Root certificate for howsmyssl.com
const char IRG_Root_X1 [] PROGMEM = R"CERT(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)CERT";
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create a list of certificates with the server certificate
X509List cert(IRG_Root_X1);
void setup() {
Serial.begin(115200);
//Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
//Connect to Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
// Set time via NTP, as required for x.509 validation
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
Serial.print("Waiting for NTP time sync: ");
time_t now = time(nullptr);
while (now < 8 * 3600 * 2) {
delay(500);
Serial.print(".");
now = time(nullptr);
}
Serial.println("");
struct tm timeinfo;
gmtime_r(&now, &timeinfo);
Serial.print("Current time: ");
Serial.print(asctime(&timeinfo));
}
void loop() {
WiFiClientSecure client;
// wait for WiFi connection
if ((WiFi.status() == WL_CONNECTED)) {
client.setTrustAnchors(&cert);
HTTPClient https;
Serial.print("[HTTPS] begin...\n");
if (https.begin(client, "https://www.howsmyssl.com/a/check")) { // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
int httpCode = https.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
https.end();
} else {
Serial.printf("[HTTPS] Unable to connect\n");
}
}
Serial.println();
Serial.println("Waiting 2min before the next round...");
delay(10000);
}
This example does exactly the same thing as the previous ones (makes a request to the www.howsmyssl.com website), but it checks the server certificate. You can make a request to any other website, as long as you get its server certificate.
For this section, you’ll need the server certificate (see this section to learn how to get the server certificate).
How does the Code Work?
This example is similar to the previous ones but adds the required lines to check the server certificate.
First, include the required libraries. You’ll use the WiFiClientSecure library to make requests using TLS, and the ESP8266HTTPClient library to make it easy to make the requests.
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266HTTPClient.h>
The server root certificate for the howsmyssl.com website is saved on the IRG_Root_X1 variable.
// Root certificate for howsmyssl.com
const char IRG_Root_X1 [] PROGMEM = R"CERT(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)CERT";
Insert your network credentials in the following lines:
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Then, you need to create a list of certificates cert (even if you only have one certificate) with the server certificate you want to use:
// Create a list of certificates with the server certificate
X509List cert(IRG_Root_X1);
In the setup(), you need to configure the time on the ESP8266, which is necessary to validate the certificate.
// Set time via NTP, as required for x.509 validation
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
Serial.print("Waiting for NTP time sync: ");
time_t now = time(nullptr);
while (now < 8 * 3600 * 2) {
delay(500);
Serial.print(".");
now = time(nullptr);
}
Serial.println("");
struct tm timeinfo;
gmtime_r(&now, &timeinfo);
Serial.print("Current time: ");
Serial.print(asctime(&timeinfo));
First, to make an HTTPS request, you need to create a WiFiClientSecure object.
WiFiClientSecure client;
Then, you need to tell which certificates the client can trust using the setTrustAnchors() method and passing as an argument the certificate list cert (in this case, we only added one certificate).
client.setTrustAnchors(&cert);
From now on, the code is the same as the previous projects.
You need to create an HTTPClient instance (https), initialize the https client on the host specified using the begin() method, and then, handle the server response.
client.setTrustAnchors(&cert);
HTTPClient https;
Serial.print("[HTTPS] begin...\n");
if (https.begin(client, "https://www.howsmyssl.com/a/check")) { // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
int httpCode = https.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
After uploading this code to the ESP8266 board, you should get the same messages on the Serial Monitor as in the previous examples.
ESP8266 HTTPS Requests – Root Store
Instead of just saving one certificate on the ESP8266, you can save multiple certificates. You can add two, three, or more certificates, and you can even add a root store. As we’ve seen previously, a root store is a database of root certificates that your browser or operating system can trust.
You can download the entire Mozilla Certificate store, and upload it to your ESP8266 so that it behaves like a browser. So, you’ll be able to make HTTPS requests securely to any server (that uses TLS) without having to hardcode its certificate.
This article is already quite long, so we’ll cover this subject in another tutorial (to be published soon).
If you’re curious about this topic, I recommend taking a look at the ESP8266 Certificate Store official example: BearSSL_CertStore. You can also find it on your Arduino IDE: File > Examples > ESP8266WiFi > BearSSL_CertStore.
Wrapping Up
In this tutorial, you learned how to make HTTPS requests with the ESP8266.
We’ve shown you different ways to make HTTPS requests with the ESP8266: without a certificate, with a fingerprint, and with a certificate. It’s also possible to use multiple certificates or a root storeâwe’ll cover this subject in a future tutorial. You also learned about the basic concepts of HTTPS protocol and about SSL/TLS certificates.
Other related tutorials that you may find interesting:
We hope you found this tutorial useful. We intend to create more tutorials about HTTPS and secure communication. Let us know in the comments below what you think.
Learn more about the ESP8266 with our resources:
- Home Automation using ESP8266
- Build Web Servers with ESP32 and ESP8266
- Firebase Web App with ESP32 and ESP8266
- Free ESP8266 Projects and TutorialsâŠ
Thanks for reading.
Super Thank you,
I Have A Doubt, What Is The Use Of Certificate Store In Arduino Data Folder or Code ?
Hi.
What do you mean? Can you better explain?
I don’t think i understood your question.
Regards,
Sara
Hello
I’m new to programming. How can I add two or more certificates? Thanks
At this step:
”
Then, you need to create a list of certificates cert (even if you only have one certificate) with the server certificate you want to use:
// Create a list of certificates with the server certificate
X509List cert(IRG_Root_X1);
“
Hi.
Imagine your other certificate is called IRG_Root_X2.
You just have to append it to the list like this:
cert.append(IRG_Root_X2);
Before calling
client.setTrustAnchors(&cert);
I hope this helps.
Regards,
Sara
OK, thanks a lot for the help
Very good tutorial!
Regarding Certificates store you told you will publish another tutorial soon.
When do you think to publish?
Thank you.
Best regards Reinhard
Fantastic tutorial⊠Thanks
One question⊠what if the HTTPS server requires credentials (username and password), how do you pass these into your GET Request ?
Thanks in advance for your answer
Thank you
One question – which release of esp8266 supports setInsecure? I guess version 2.4.2 does not support – right? Please let me know which version do you recommend?
Best regards
Jui
Hi.
Why you say it doesn’t support? Have you tried it out?
I’m not sure if there are versions that don’t support it.
Regards,
Sara
Yes, I tried it and the Compiler stopped wirh âsetInsecureâ is not defined with V 2.4.2 of esp8266.. It is very very helpful when you note in the tutorial all the version of used libraries and of your environment. E.g. this Tutorial based or tested on Arduino 1.18.5, Esp lib 2.6.3âŠ.. sometime it is a nightmare to find the working versions.
That would be great, thank you in advance.
Just wanted to thank you for this tutorial. It was very helpful and I was able to implement it relatively easily. My HTTPS comms are up and running. Thank you! đđđ
Hi Sara,
I tried setting up a no certificate request per your example. It returns a code 200, but the payload variable is empty. But if I take the same request and send it via my browser I get back the response I’m seeking. So something about the no certificate request is not right. Any thoughts?