Table of Contents
![ESP32 HTTPS Requests Arduino IDE](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/ESP32-HTTPS-Requests.jpg?resize=828%2C466&quality=100&strip=all&ssl=1)
Throughout this article, we’ll cover the list below subjects:
To recognize how to make HTTPS requests with the ESP32, it’s better to be acquainted with some fundamental concepts that we’ll describe following.
The WiFiClient library gives some info concerning exactly how to utilize a certificate package on the adhering to web link:
Introduction
I followed all the guidelines provided, as well as got the following concern:
What is HTTPS?
If anybody knows how to repair this concern, please share in the comments listed below.
If you want to skip the SSL web server certificate verification, but you still desire to have actually secured communication, you can eliminate the complying with line:
![HTTP vs HTTPS](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/HTTP-vs-HTTPS.png?resize=750%2C500&quality=100&strip=all&ssl=1)
And add the adhering to line before starting the HTTP customer:
Why do you need HTTPS with the ESP32?
The full instance can be found listed below.
Table of Contents
![ESP32 HTTPS requests encrypted](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/ESP32-HTTPS-Requests-encryption.png?resize=670%2C308&quality=100&strip=all&ssl=1)
Throughout this write-up, we’ll cover the list below subjects:
To understand exactly how to make HTTPS demands with the ESP32, it’s better to be familiar with some basic ideas that we’ll discuss next.
![SSL/TLS Certificate valid](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/SSL-TLS-certificate_SSL-certificate.png?resize=472%2C163&quality=100&strip=all&ssl=1)
TLS/SSL Certificates
This instance develops a protected link with the www.howsmyssl.com site and also checks its certification to guarantee we’re attached to the server that we expect.
![TLS SSL Certificate Public Key](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/TLS-SSL-Certificate-Public-Key.png?resize=351%2C163&quality=100&strip=all&ssl=1)
If you want to miss the SSL web server certificate verification, yet you still want to have encrypted communication, you can get rid of the complying with line:
![trusted root certificates chrome](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/trusted-root-certificates.png?resize=505%2C467&quality=100&strip=all&ssl=1)
And include the following line prior to linking with the client:
![HTTPS client server interaction with valid certificate](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/HTTPS-browser-valid-certificate.png?resize=750%2C468&quality=100&strip=all&ssl=1)
The full example can be found listed below.
![ESP32 Check server certificate for secure connection](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/ESP32-check-server-certificate.png?resize=750%2C354&quality=100&strip=all&ssl=1)
The WiFiClient library provides some info concerning exactly how to utilize a certificate package on the adhering to web link:
Certificate Chain
I complied with all the instructions given, and also obtained the following issue:
If any person knows exactly how to repair this problem, please share in the remarks below.
- root certificate (from a Certificate Authority);
- one or more intermediate certificates;
- the server certificate.
If you want to avoid the SSL web server certificate verification, but you still desire to have encrypted interaction, you can get rid of the complying with line:
And include the adhering to line before beginning the HTTP client:
![Certificate Chain SSL](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/certificate-hierarchy-github.png?resize=546%2C669&quality=100&strip=all&ssl=1)
The complete example can be located listed below.
![github secure icon](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/github-secure-icon.png?resize=456%2C134&quality=100&strip=all&ssl=1)
The following diagram shows a high-level overview of how it works.
![certificate chain example](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/12/certificate-chain-f_certificate-chain.png?resize=750%2C395&quality=100&strip=all&ssl=1)
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 private 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 private 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 ESP32, to check the validity of a server, you can load any of those certificates: root, intermediate, or server certificate.
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.
So, if you want to use it in your ESP32 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.
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 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.
One of the examples we’ll use later is 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.
![get website ssl certificate](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/google-chrome-get-website-certificate-1.png?resize=719%2C372&quality=100&strip=all&ssl=1)
- Then, click on Show certificate.
![show certificate google chrome](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/google-chrome-get-website-certificate-2.png?resize=719%2C372&quality=100&strip=all&ssl=1)
- A new window will open the 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…
![ssl certificate details](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/google-chrome-get-website-certificate-3.png?resize=546%2C668&quality=100&strip=all&ssl=1)
- 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 to check it’s details, including the expiration date.
![all the ssl certificate information](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/certificate-information.png?resize=405%2C515&quality=100&strip=all&ssl=1)
Open the certificate using Notepad or other similar software. You should get something similar as shown below.
![certificate notepad](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/root-certificate-notepad.png?resize=615%2C805&quality=100&strip=all&ssl=1)
We need to convert this to Arduino multi-line string, so that we can use it in our sketch. Basically, you need to add a “ at the beginning of each line and a /n” / at the end of each line, except the last line that you should add /n”. So, you’ll get something as shown below:
![certificate multi line string](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/certificate-multiline-string.png?resize=653%2C824&quality=100&strip=all&ssl=1)
HTTPS Requests with the ESP32
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 on the ESP32 using the Arduino core. We’ll cover different methods using two different libraries: WiFiClientSecure and HTTPClient.
![HTTPS Requests with the ESP32](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/ESP32-HTTPS-Requests.png?resize=750%2C320&quality=100&strip=all&ssl=1)
ESP32 HTTPS Requests using WiFiClientSecure Library
You can find a simple example showing how to make HTTPS requests with the WiFiClientSecure library on your Arduino IDE.
ESP32 HTTPS Requests with Certificate
Make sure you have an ESP32 board selected in Tools > Board. Then, go to File > Examples > WiFiClientSecure > WiFiClientSecure.
You can modify the following code with the certificate we got from the previous steps, which is valid until 2035.
/*
Complete project details: https://RandomNerdTutorials.com/esp32-https-requests/
Wifi secure connection example for ESP32 - Running on TLS 1.2 using mbedTLS
Suporting the following chipersuites:
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_CCM","TLS_DHE_RSA_WITH_AES_256_CCM","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384","TLS_DHE_RSA_WITH_AES_256_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","TLS_DHE_RSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8","TLS_DHE_RSA_WITH_AES_256_CCM_8","TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_DHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CCM","TLS_DHE_RSA_WITH_AES_128_CCM","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256","TLS_DHE_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","TLS_DHE_RSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8","TLS_DHE_RSA_WITH_AES_128_CCM_8","TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA","TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_DHE_PSK_WITH_AES_256_GCM_SHA384","TLS_DHE_PSK_WITH_AES_256_CCM","TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384","TLS_DHE_PSK_WITH_AES_256_CBC_SHA384","TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA","TLS_DHE_PSK_WITH_AES_256_CBC_SHA","TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_PSK_DHE_WITH_AES_256_CCM_8","TLS_DHE_PSK_WITH_AES_128_GCM_SHA256","TLS_DHE_PSK_WITH_AES_128_CCM","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256","TLS_DHE_PSK_WITH_AES_128_CBC_SHA256","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA","TLS_DHE_PSK_WITH_AES_128_CBC_SHA","TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_PSK_DHE_WITH_AES_128_CCM_8","TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA","TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA","TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_256_CCM","TLS_RSA_WITH_AES_256_CBC_SHA256","TLS_RSA_WITH_AES_256_CBC_SHA","TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA","TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA","TLS_RSA_WITH_AES_256_CCM_8","TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA","TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_RSA_WITH_AES_128_CCM","TLS_RSA_WITH_AES_128_CBC_SHA256","TLS_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA","TLS_RSA_WITH_AES_128_CCM_8","TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA","TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_RSA_PSK_WITH_AES_256_GCM_SHA384","TLS_RSA_PSK_WITH_AES_256_CBC_SHA384","TLS_RSA_PSK_WITH_AES_256_CBC_SHA","TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_RSA_PSK_WITH_AES_128_GCM_SHA256","TLS_RSA_PSK_WITH_AES_128_CBC_SHA256","TLS_RSA_PSK_WITH_AES_128_CBC_SHA","TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA","TLS_PSK_WITH_AES_256_GCM_SHA384","TLS_PSK_WITH_AES_256_CCM","TLS_PSK_WITH_AES_256_CBC_SHA384","TLS_PSK_WITH_AES_256_CBC_SHA","TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_PSK_WITH_AES_256_CCM_8","TLS_PSK_WITH_AES_128_GCM_SHA256","TLS_PSK_WITH_AES_128_CCM","TLS_PSK_WITH_AES_128_CBC_SHA256","TLS_PSK_WITH_AES_128_CBC_SHA","TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_PSK_WITH_AES_128_CCM_8","TLS_PSK_WITH_3DES_EDE_CBC_SHA","TLS_EMPTY_RENEGOTIATION_INFO_SCSV"]
2017 - Evandro Copercini - Apache 2.0 License.
*/
#include <WiFiClientSecure.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const char* server = "www.howsmyssl.com"; // Server URL
// www.howsmyssl.com root certificate authority, to verify the server
// change it to your server root CA
// SHA1 fingerprint is broken now!
const char* test_root_ca= /
"-----BEGIN CERTIFICATE-----/n" /
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw/n" /
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh/n" /
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4/n" /
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu/n" /
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY/n" /
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc/n" /
"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+/n" /
"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U/n" /
"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW/n" /
"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH/n" /
"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC/n" /
"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv/n" /
"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn/n" /
"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn/n" /
"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw/n" /
"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI/n" /
"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV/n" /
"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq/n" /
"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL/n" /
"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ/n" /
"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK/n" /
"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5/n" /
"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur/n" /
"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC/n" /
"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc/n" /
"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq/n" /
"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA/n" /
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d/n" /
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=/n" /
"-----END CERTIFICATE-----/n";
// You can use x.509 client certificates if you want
//const char* test_client_key = ""; //to verify the client
//const char* test_client_cert = ""; //to verify the client
WiFiClientSecure client;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
delay(100);
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
// attempt to connect to Wifi network:
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
// wait 1 second for re-trying
delay(1000);
}
Serial.print("Connected to ");
Serial.println(ssid);
client.setCACert(test_root_ca);
//client.setCertificate(test_client_cert); // for client verification
//client.setPrivateKey(test_client_key); // for client verification
Serial.println("/nStarting connection to server...");
if (!client.connect(server, 443))
Serial.println("Connection failed!");
else {
Serial.println("Connected to server!");
// Make a HTTP request:
client.println("GET https://www.howsmyssl.com/a/check HTTP/1.0");
client.println("Host: www.howsmyssl.com");
client.println("Connection: close");
client.println();
while (client.connected()) {
String line = client.readStringUntil('/n');
if (line == "/r") {
Serial.println("headers received");
break;
}
}
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
Serial.write(c);
}
client.stop();
}
}
void loop() {
// do nothing
}
This example establishes a secure connection with the www.howsmyssl.com website and checks its certificate to ensure we’re connected to the server that we expect.
If you’re used to making HTTP requests with the ESP32 using the WiFiClient library, this example is not much different.
How does the Code Work?
You need to include the WiFiClientSecure library.
#include <WiFiClientSecure.h>
Insert your network credentials in the following lines.
const char* ssid = "REPLACE_WITH_YOUR_SSID"; // your network SSID (name of wifi network)
const char* password = "REPLACE_WITH_YOUR_PASSWORD"; // your network password
Insert the server URL. In this case, we’ll make a request to www.howsmyssl.com. This website will return how good the SSL of the client is (in this case, the ESP32).
const char* server = "www.howsmyssl.com"; // Server URL
Then, you need to insert the server certificate. We’re using the root certificate.
const char* test_root_ca= /
"-----BEGIN CERTIFICATE-----/n" /
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw/n" /
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh/n" /
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4/n" /
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu/n" /
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY/n" /
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc/n" /
"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+/n" /
"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U/n" /
"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW/n" /
"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH/n" /
"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC/n" /
"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv/n" /
"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn/n" /
"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn/n" /
"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw/n" /
"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI/n" /
"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV/n" /
"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq/n" /
"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL/n" /
"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ/n" /
"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK/n" /
"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5/n" /
"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur/n" /
"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC/n" /
"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc/n" /
"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq/n" /
"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA/n" /
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d/n" /
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=/n" /
"-----END CERTIFICATE-----/n";
Create a new client called client using WiFiClient secure.
WiFiClientSecure client;
In the setup(), initialize the Serial Monitor and connect to your network.
//Initialize serial and wait for port to open:
Serial.begin(115200);
delay(100);
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
// attempt to connect to Wifi network:
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
// wait 1 second for re-trying
delay(1000);
}
Serial.print("Connected to ");
Serial.println(ssid);
The following line set the client certificate using the setCACert() method on the client.
client.setCACert(test_root_ca);
Then, the client connects to the server. For HTTPS, you need to use port 443.
if (!client.connect(server, 443))
Serial.println("Connection failed!");
If the connection is successful, we can make the HTTP request. In this case, we’re making a GET request. Note that you need to use the https:// before the URL you’ll make a request to.
else {
Serial.println("Connected to server!");
// Make a HTTP request:
client.println("GET https://www.howsmyssl.com/a/check HTTP/1.0");
client.println("Host: www.howsmyssl.com");
client.println("Connection: close");
client.println();
Finally, we get and print the response from the server:
while (client.connected()) {
String line = client.readStringUntil('/n');
if (line == "/r") {
Serial.println("headers received");
break;
}
}
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
Serial.write(c);
}
In the end, we close the connection with the client.
client.stop();
In this example, we make the request once in the setup(). The loop() is empty, but you can add any other tasks that you need in your project. Or, depending on the application, you can make the request on the loop().
void loop() {
// do nothing
}
In summary, to make HTTPS requests:
- Include the WiFiClientSecure library;
- Create a WiFiClientSecure client;
- Use port 443;
- Use the setCACert() function to set the client certificate.
- Use https on the URL when making the HTTPS request.
Demonstration
Upload the code to your board.
Open the Serial Monitor at a baud rate of 115200 and press the onboard RST button.
You should get something as shown in the following screenshot.
![ESP32 WiFiClientSecure example Serial Monitor](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/WiFiClientSecure-ESP32-Serial-Monitor.png?resize=644%2C413&quality=100&strip=all&ssl=1)
If you scroll to the right, you’ll get the result of how secure the connection is. You should get a “Probably Okay”.
![ESP32 WiFiClientSecure example Serial Monitor](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/WiFiClientSecure-ESP32-Serial-Monitor-2.png?resize=644%2C413&quality=100&strip=all&ssl=1)
ESP32 HTTPS Requests without Certificate
If you want to skip the SSL server certificate verification, but you still want to have encrypted communication, you can remove the following line:
client.setCACert(test_root_ca);
And add the following line before connecting with the client:
client.setInsecure();
The complete example can be found below.
/*
Complete project details: https://RandomNerdTutorials.com/esp32-https-requests/
Based on the WiFiClientSecure example HTTPS Requests without Certificate
Wifi secure connection example for ESP32
Running on TLS 1.2 using mbedTLS
Suporting the following chipersuites:
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_CCM","TLS_DHE_RSA_WITH_AES_256_CCM","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384","TLS_DHE_RSA_WITH_AES_256_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","TLS_DHE_RSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8","TLS_DHE_RSA_WITH_AES_256_CCM_8","TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_DHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CCM","TLS_DHE_RSA_WITH_AES_128_CCM","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256","TLS_DHE_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","TLS_DHE_RSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8","TLS_DHE_RSA_WITH_AES_128_CCM_8","TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA","TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_DHE_PSK_WITH_AES_256_GCM_SHA384","TLS_DHE_PSK_WITH_AES_256_CCM","TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384","TLS_DHE_PSK_WITH_AES_256_CBC_SHA384","TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA","TLS_DHE_PSK_WITH_AES_256_CBC_SHA","TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_PSK_DHE_WITH_AES_256_CCM_8","TLS_DHE_PSK_WITH_AES_128_GCM_SHA256","TLS_DHE_PSK_WITH_AES_128_CCM","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256","TLS_DHE_PSK_WITH_AES_128_CBC_SHA256","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA","TLS_DHE_PSK_WITH_AES_128_CBC_SHA","TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_PSK_DHE_WITH_AES_128_CCM_8","TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA","TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA","TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_256_CCM","TLS_RSA_WITH_AES_256_CBC_SHA256","TLS_RSA_WITH_AES_256_CBC_SHA","TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA","TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA","TLS_RSA_WITH_AES_256_CCM_8","TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA","TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_RSA_WITH_AES_128_CCM","TLS_RSA_WITH_AES_128_CBC_SHA256","TLS_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA","TLS_RSA_WITH_AES_128_CCM_8","TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA","TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_RSA_PSK_WITH_AES_256_GCM_SHA384","TLS_RSA_PSK_WITH_AES_256_CBC_SHA384","TLS_RSA_PSK_WITH_AES_256_CBC_SHA","TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_RSA_PSK_WITH_AES_128_GCM_SHA256","TLS_RSA_PSK_WITH_AES_128_CBC_SHA256","TLS_RSA_PSK_WITH_AES_128_CBC_SHA","TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA","TLS_PSK_WITH_AES_256_GCM_SHA384","TLS_PSK_WITH_AES_256_CCM","TLS_PSK_WITH_AES_256_CBC_SHA384","TLS_PSK_WITH_AES_256_CBC_SHA","TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_PSK_WITH_AES_256_CCM_8","TLS_PSK_WITH_AES_128_GCM_SHA256","TLS_PSK_WITH_AES_128_CCM","TLS_PSK_WITH_AES_128_CBC_SHA256","TLS_PSK_WITH_AES_128_CBC_SHA","TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_PSK_WITH_AES_128_CCM_8","TLS_PSK_WITH_3DES_EDE_CBC_SHA","TLS_EMPTY_RENEGOTIATION_INFO_SCSV"]
2017 - Evandro Copercini - Apache 2.0 License.
*/
#include <WiFiClientSecure.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const char* server = "www.howsmyssl.com"; // Server URL
WiFiClientSecure client;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
delay(100);
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
// attempt to connect to Wifi network:
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
// wait 1 second for re-trying
delay(1000);
}
Serial.print("Connected to ");
Serial.println(ssid);
client.setInsecure();
Serial.println("/nStarting connection to server...");
if (!client.connect(server, 443))
Serial.println("Connection failed!");
else {
Serial.println("Connected to server!");
// Make a HTTP request:
client.println("GET https://www.howsmyssl.com/a/check HTTP/1.0");
client.println("Host: www.howsmyssl.com");
client.println("Connection: close");
client.println();
while (client.connected()) {
String line = client.readStringUntil('/n');
if (line == "/r") {
Serial.println("headers received");
break;
}
}
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
Serial.write(c);
}
client.stop();
}
}
void loop() {
// do nothing
}
With this example, your connection is still encrypted, but you won’t be sure if you’re talking to the right server. This scenario is useful for testing purposes.
ESP32 HTTPS Requests with Certificate Bundle
Instead of just using one certificate, you can use a certificate bundle: a collection of trusted certificates that you can load into your board. Then, you don’t have to worry about getting the certificate for a specific server.
The WiFiClient library provides some information about how to use a certificate bundle on the following link:
I followed all the instructions provided, and got the following issue:
[ 1799][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-12288) X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed
If anyone knows how to fix this issue, please share in the comments below.
ESP32 HTTP Requests using HTTPClient Library
The HTTPClient library provides a simple example showing how to make HTTPS requests with the ESP32. You can find the example in your Arduino IDE. First, make sure you have an ESP32 board selected in Tools > Board. Then, go to File > Examples > HTTPClient > BasicHttpsClient. We created new sketches based on that example. See the code below.
ESP32 HTTPS Requests with Certificate
The following sketch makes a request to howsmyssl.com like the previous examples but uses the HTTPClient library. It checks the server certificate. We’ll use the root certificate we’ve gotten in previous steps.
/*
Complete project details: https://RandomNerdTutorials.com/esp32-https-requests/
Based on the BasicHTTPSClient.ino example found at Examples > BasicHttpsClient
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// www.howsmyssl.com root certificate authority, to verify the server
// change it to your server root CA
const char* rootCACertificate = /
"-----BEGIN CERTIFICATE-----/n" /
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw/n" /
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh/n" /
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4/n" /
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu/n" /
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY/n" /
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc/n" /
"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+/n" /
"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U/n" /
"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW/n" /
"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH/n" /
"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC/n" /
"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv/n" /
"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn/n" /
"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn/n" /
"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw/n" /
"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI/n" /
"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV/n" /
"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq/n" /
"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL/n" /
"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ/n" /
"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK/n" /
"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5/n" /
"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur/n" /
"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC/n" /
"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc/n" /
"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq/n" /
"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA/n" /
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d/n" /
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=/n" /
"-----END CERTIFICATE-----/n";
void setup() {
Serial.begin(115200);
Serial.println();
// Initialize Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
void loop() {
WiFiClientSecure *client = new WiFiClientSecure;
if(client) {
// set secure client with certificate
client->setCACert(rootCACertificate);
//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) {
// print server response payload
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?
Start by including the required libraries: WiFi.h, WiFiClientSecure.h, and HTTPClient.h.
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.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";
Next, you need to add the server certificate. We’re using the root certificate for howsmyssl.com (see previous steps).
const char* rootCACertificate = /
"-----BEGIN CERTIFICATE-----/n" /
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw/n" /
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh/n" /
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4/n" /
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu/n" /
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY/n" /
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc/n" /
"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+/n" /
"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U/n" /
"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW/n" /
"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH/n" /
"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC/n" /
"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv/n" /
"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn/n" /
"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn/n" /
"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw/n" /
"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI/n" /
"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV/n" /
"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq/n" /
"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL/n" /
"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ/n" /
"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK/n" /
"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5/n" /
"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur/n" /
"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC/n" /
"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc/n" /
"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq/n" /
"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA/n" /
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d/n" /
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=/n" /
"-----END CERTIFICATE-----/n";
In the setup () initialize the Serial Monitor and connect to Wi-Fi.
void setup() {
Serial.begin(115200);
Serial.println();
// Initialize Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
In the loop(), create a pointer to WiFiClientSecure called client.
WiFiClientSecure *client = new WiFiClientSecure;
Set a secure client with the certificate using the setCACert() method:
client->setCACert(rootCACertificate);
Then, 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 ESP32 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) {
// print server response payload
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 can change it depending on your project requirements.
Serial.println("Waiting 2min before the next round...");
delay(120000);
Demonstration
You can change the debug level to get more information about what’s going on in the process. Go to Tools > Core Debug Level > Debug. Then, you can upload the code to the ESP32.
After uploading the code, open the Serial Monitor at a baud rate of 115200. Press the on-board RST board to start running the newly uploaded code.
You should get something similar as shown in the picture below.
![Demonstration HTTPs request ESP32 with response payload](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/ESP32-HTTPS-Client-Demonstration-Serial-Monitor-1.png?resize=602%2C506&quality=100&strip=all&ssl=1)
If you scroll to the right, you’ll get the result of how secure the connection is. You should get a “Probably Okay”.
ESP32 HTTPS Requests without Certificate
If you want to skip the SSL server certificate verification, but you still want to have encrypted communication, you can remove the following line:
client.setCACert(test_root_ca);
And add the following line before starting the HTTP client:
client.setInsecure();
The complete example can be found below.
/*
Complete project details: https://RandomNerdTutorials.com/esp32-https-requests/
Based on the BasicHTTPSClient.ino example found at Examples > BasicHttpsClient
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.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.println();
// Initialize Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
void loop() {
WiFiClientSecure *client = new WiFiClientSecure;
if(client) {
// set secure client without certificate
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) {
// print server response payload
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);
}
With this example, your connection is still encrypted, but you won’t be sure if you’re talking to the right server. This scenario is useful for testing purposes.
After uploading this example, here’s what you should get:
![Demonstration HTTPs request ESP32](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/11/ESP32-HTTPS-Client-No-Certificate-Demonstration-Serial-Monitor-1.png?resize=828%2C500&quality=100&strip=all&ssl=1)
Your connection is still encrypted, but it will skip SSL verification.
Wrapping Up
In this tutorial, you learned how to make HTTPS requests with the ESP32. You also learned about the basic concepts of .
We’ve taken a look at examples with the WiFiClientSecure and HTTPClient libraries. The examples presented are as simple as possible so that you can modify them and apply them to your own projects. You learned how to make HTTPS requests with and without verification of the SSL/TLS certificate.
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 ESP32 with our resources:
Thanks for reading.