ESP32 HTTPS
#include <>
From:https://randomnerdtutorials.com/esp32-https-requests/
ESP32 HTTPS Requests (Arduino IDE) Introduction Demonstration HTTPS Request ESP32 What Is Https
Why Do You Need HTTPS With the ESP32 TLS SSL Certificates Certificate Chain In Summary
Certificates Expiration Date Getting a Servers Certificate Getting a Server Cert Using Google Chrome How To Get a Website Cert Using google Chrome
HTTPS Requests With the ESP32 ESP32 HTTPS Requests Using WificlientSecure Lib ESP32 HTTPS Requests With Cert How Does the Code Work
Demonstration ESP32 HTTPS Requests Without Cert ESP32 HTTPS Reauests With Cert Bundle ESP32 HTTP Requests Using Http Client Lib
Wrapping Up


ESP32 HTTPS Requests ( Arduino IDE )
In this guide, you’ll learn how to make HTTPS requests with the ESP32. We’ll introduce you to some HTTPS fundamental concepts and provide several examples ( with and without certificates ) using two different libraries: HttpClient and WiFiClientSecure. ESP32 HTTPS Requests Arduino IDE Throughout this article, we’ll cover the following subjects: What is HTTPS? Why do you need HTTPS with the ESP32? SSL/TLS Certificates Certificate Chain Certificates Expiration Date Getting a Server’s Certificate using Google Chrome HTTPS Requests with the ESP32 ( WiFiClientSecure ) ESP32 HTTPS Requests with Certificate ESP32 HTTPS Requests without Certificate HTTPS Requests with the ESP32 ( HTTPClient ) ESP32 HTTPS Requests with Certificate ESP32 HTTPS Requests without Certificate
Introduction
To understand how to make HTTPS requests with the ESP32, 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: ESP32/ESP8266 with HTTPS and SSL/TLS Encryption: Basic Concepts
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. HTTP vs HTTPS To simplify, HTTPS is just the HTTP protocol but with encrypted data using SSL/TLS.
Why do you need HTTPS with the ESP32?
Using HTTPS ensures the following: 1 ) Encryption: all traffic between the ESP32 and a server will be encrypted—no one can spy on your requests and passwords, they will only see gibberish. ESP32 HTTPS requests encrypted When using the ESP32 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. SSL/TLS Certificate valid To make sure we are connected to the right server, we need to check the server certificate on the ESP32. This means we need to download the server certificate 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. TLS SSL Certificate Public Key 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. trusted root certificates chrome 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. HTTPS client server interaction with valid certificate When you’re using an ESP32, 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. ESP32 Check server certificate for secure connection 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: 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. Certificate Chain SSL 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. github secure icon The following diagram shows a high-level overview of how it works. certificate chain example
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 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. 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?
  1. Go to the website that you want to get the certificate for.
  2. Click on the padlock icon and then click on Show connection details. get website ssl certificate
  3. Then, click on Show certificate. show certificate google chrome
  4. 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
  5. 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 Open the certificate using Notepad or other similar software. You should get something similar as shown below. certificate notepad 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 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
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.
/H******************************************************** Complete project details: https://RandomNerdTutorials.com/ 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> //************************* DEFINES ************************************ //************************* PROTOTYPES ************************************ //************************* VARIABLES ************************************ /*F******************************************************************** * **********************************************************************/ 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" \ "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\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; /*F******************************************************************** * **********************************************************************/ void setup() { Serial.begin( BAUD ); // INITIALIZE SERIAL AND WAIT FOR PORT TO OPEN delay( 100 ); Serial.print( "Attempting to connect to SSID: " ); Serial.println( ssid ); WiFi.begin( ssid, password ); while( WiFi.status() != WL_CONNECTED ) // ATTEMPT TO CONNECT TO Wifi NET { 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 SERVER, READ AND PRINT THEM while( client.available() ) { char c = client.read(); Serial.write( c ); } client.stop(); } } /*F******************************************************************** * **********************************************************************/ 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" \ "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\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.
/*H******************************************************************** * Initialize serial and wait for port to open: **********************************************************************/ Serial.begin( BAUD ); 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 SERVER, READ 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().
/*F******************************************************************** * **********************************************************************/ void loop() { // do nothing }
In summary, to make HTTPS requests:
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 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
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.
/*H******************************************************* Complete project details: https://RandomNerdTutorials.com/ 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> //************************* DEFINES ************************************ #define BAUD 9600 const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD"; const char* server = "www.howsmyssl.com"; // Server URL //************************* PROTOTYPES ************************************ //************************* VARIABLES ************************************ WiFiClientSecure client; /*F******************************************************************** * **********************************************************************/ void setup() { Serial.begin( BAUD ); // INIT SERIAL AND WAIT FOR PORT TO OPEN 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 INCOMING BYTES AVAILABLE FROM SERVER, READ AND PRINT THEM while( client.available() ) { char c = client.read(); Serial.write( c ); } client.stop(); } } /*F******************************************************************** * **********************************************************************/ 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. /*H******************************************************* Complete project details: https://RandomNerdTutorials.com/ Based on the BasicHTTPSClient.ino example found at Examples > BasicHttpsClient ********************************************************/ #include <Arduino.h> #include <WiFi.h> #include <WiFiClientSecure.h> #include <HTTPClient.h> //************************* DEFINES ************************************ const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD"; //************************* PROTOTYPES ************************************ //************************* VARIABLES ************************************ // www.howsmyssl.com root certificate authority, to verify the server // change it to your server root CA const char* rootCACertificate = \ "-----BEGIN CERTIFICATE-----\n" \ "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\n" \ "-----END CERTIFICATE-----\n"; /*F******************************************************************** * **********************************************************************/ void setup() { Serial.begin( BAUD ); Serial.println(); WiFi.mode( WIFI_STA ); // Init Wi-Fi WiFi.begin( ssid, password ); Serial.print( "Connecting to WiFi .." ); while( WiFi.status() != WL_CONNECTED ) { Serial.print( '.' ); delay( 1000 ); } Serial.println( WiFi.localIP() ); } /*F******************************************************************** * **********************************************************************/ 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.
/*F******************************************************************** * **********************************************************************/ #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" \ "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\n" \ "-----END CERTIFICATE-----\n";
In the setup () initialize the Serial Monitor and connect to Wi-Fi.
/*F******************************************************************** * **********************************************************************/ void setup() { Serial.begin( BAUD ); 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 epending 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 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.
/*H******************************************************* Complete project details: https://RandomNerdTutorials.com/ Based on the BasicHTTPSClient.ino example found at Examples > BasicHttpsClient ********************************************************/ #include <Arduino.h> #include <WiFi.h> #include <WiFiClientSecure.h> #include <HTTPClient.h> //************************* DEFINES ************************************ #define BAUD 9600 const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD"; //************************* PROTOTYPES ************************************ //************************* VARIABLES ************************************ /*F******************************************************************** * **********************************************************************/ void setup() { Serial.begin( BAUD ); Serial.println(); // Init 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() ); } /*F******************************************************************** * **********************************************************************/ void loop() { WiFiClientSecure *client = new WiFiClientSecure; if( client ) { client->setInsecure(); // SET SECURE CLIENT WITH CERTIFICATE HTTPClient https; //CREATE AN HTTPClient INSTANCE // INIT AN HTTPS COMMUNICATION USING 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(); if( httpCode > 0 ) // HttpCode WILL BE NEGATIVE ON ERROR { // 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(); // PRINT SERVER RESPONSE PAYLOAD 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
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 HTTPS protocol and about SSL/TLS certificates. 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: Learn ESP32 with Arduino IDE Build Web Servers with ESP32 and ESP8266 Firebase Web App with ESP32 and ESP8266 Free ESP32 Projects and Tutorials