Requêtes HTTPS ESP32 (IDE Arduino)

Requêtes HTTPS ESP32 (IDE Arduino)

Dans ce guide, vous apprendrez à faire des requêtes HTTPS avec l’ESP32. Nous vous présenterons quelques concepts fondamentaux de HTTPS et fournirons plusieurs exemples (avec et sans certificats) utilisant deux bibliothèques différentes : HttpClient et WiFiClientSecure.

Requêtes HTTPS ESP32 IDE Arduino

Vous utilisez une carte ESP8266 ? Consultez plutôt ce didacticiel : ESP8266 NodeMCU HTTPS Requests

Table des matières

Tout au long de cet article, nous aborderons les sujets suivants :

Introduction

Pour comprendre comment faire des requêtes HTTPS avec l’ESP32, mieux vaut se familiariser avec quelques notions fondamentales que nous expliquerons ensuite. Nous vous conseillons également de consulter l’article suivant :

Qu’est-ce que le HTTPS ?

HTTPS est la version sécurisée du protocole HTTP, d’où le « S », qui signifie sécurisé.

HTTP est un protocole de transfert de données sur Internet. Lorsque ces données sont chiffrées avec SSL/TLS, elles s’appellent HTTPS.

HTTP contre HTTPS

Pour simplifier, HTTPS n’est que le protocole HTTP mais avec des données cryptées à l’aide de SSL/TLS.

Pourquoi avez-vous besoin de HTTPS avec l’ESP32 ?

L’utilisation de HTTPS garantit ce qui suit :

1) Cryptage : tout le trafic entre l’ESP32 et un serveur sera crypté : personne ne peut espionner vos requêtes et vos mots de passe, ils ne verront que du charabia.

Requêtes HTTPS ESP32 chiffrées

Lorsque vous utilisez les bibliothèques ESP32 pour effectuer des requêtes HTTPS, elles s’occupent du chiffrement et du déchiffrement des messages.

2) Confiance du serveur (identification) : lorsque vous utilisez HTTPS, via des certificats TLS/SSL, vous vous assurez que vous êtes connecté au serveur auquel vous vous attendez, ce qui signifie que vous savez toujours à qui vous êtes connecté.

Certificat SSL/TLS valide

Pour nous assurer que nous sommes connectés au bon serveur, nous devons vérifier le certificat du serveur sur l’ESP32. Cela signifie que nous devons télécharger le certificat du serveur et le coder en dur sur notre croquis afin de pouvoir vérifier si nous sommes réellement connectés au serveur que nous attendons.

Certificats TLS/SSL

Les certificats SSL sont émis par des autorités de certification légitimes. L’un des plus connus est LetsEncrypt. Les autorités de certification confirment l’identité du propriétaire du certificat et fournissent la preuve que le certificat est valide. Le certificat contient également la clé publique du serveur pour une communication chiffrée asymétriquement avec un client.

Clé publique du certificat SSL TLS

Lorsqu’une autorité de certification émet un certificat, elle signe le certificat avec son certificat root. Ce certificat root doit se trouver dans la base de données de certificats de confiance appelée magasin root. Votre navigateur et le système d’exploitation contiennent une base de données de certificats root auxquels ils peuvent faire confiance (magasin root). La capture d’écran suivante montre certains des certificats root de confiance.

certificats racine de confiance chrome

Ainsi, lorsque vous vous connectez à un site Web à l’aide de votre navigateur, celui-ci vérifie si son certificat a été signé par un certificat root appartenant à son magasin root. De nouveaux certificats root sont ajoutés ou supprimés du magasin root à chaque mise à jour du navigateur.

Interaction serveur client HTTPS avec certificat valide

Lorsque vous utilisez un ESP32, vous devez télécharger les certificats auxquels vous faites confiance sur votre carte. Habituellement, vous n’ajouterez que le certificat du serveur auquel vous souhaitez vous connecter.

ESP32 Vérifier le certificat du serveur pour une connexion sécurisée

Mais, il est également possible de télécharger un magasin root sur votre carte pour avoir plus d’options, et vous n’avez pas à vous soucier de rechercher le certificat d’un site Web spécifique.

Chaîne de certificats

Un certificat SSL fait partie d’une chaîne de certificats SSL. Qu’est-ce qu’une chaîne de certificats ?

Une chaîne de certificats comprend les éléments suivants :

  • certificat root (d’une autorité de certification) ;
  • un ou plusieurs certificats intermédiaires ;
  • le certificat du serveur.

Le certificat de serveur est ce qui fait que votre navigateur affiche une icône de cadenas sécurisé lorsque vous visitez un site Web. Cela signifie que le serveur dispose d’un certificat SSL/TLS valide et que toutes les connexions avec le site Web sont cryptées. Un certificat SSL/TLS valide est un certificat approuvé par votre navigateur. Qu’est-ce qui le rend digne de confiance ?

Comme nous l’avons mentionné précédemment, les certificats SSL/TLS sont émis par les autorités de certification. Cependant, ces autorités ne délivrent pas de certificats directement aux sites Web. Ils utilisent des intermédiaires qui délivreront le certificat du serveur (Autorité de certification > Certificat intermédiaire > certificat du serveur). La capture d’écran suivante montre un exemple pour le site Web Github. Vous pouvez voir la hiérarchie des certificats mise en évidence par un rectangle rouge.

Chaîne de certificats SSL

Votre navigateur vérifie cette chaîne de certificats jusqu’à ce qu’il trouve le certificat root. Si ce certificat se trouve dans le magasin root du navigateur, il considère que le certificat est valide. Dans ce cas, l’autorité de certification root globale DigiCert se trouve dans le magasin root du navigateur. Ainsi, il affichera l’icône « sécurisé » sur la barre du navigateur.

icône sécurisée github

Le diagramme suivant montre un aperçu de haut niveau de son fonctionnement.

exemple de chaîne de certificats

En résumé:

  • certificat root : c’est un certificat auto-signé émis par une autorité de certification. La clé privée de ce certificat est utilisée pour signer le certificat suivant dans la hiérarchie des certificats. Les certificats root sont chargés dans les magasins de confiance des navigateurs et des systèmes d’exploitation.
  • certificat intermédiaire : il est signé par la clé privée du certificat root. La clé privée du certificat intermédiaire est celle qui signe le certificat du serveur. Il peut y avoir plus d’un certificat intermédiaire.
  • certificat de serveur : ce certificat est délivré à un nom de domaine spécifique sur un serveur. Il est signé par la clé privée du certificat intermédiaire. S’il est valide (chaîne de certificats de confiance), le navigateur affiche un badge de cadenas sécurisé dans la barre de recherche à côté du domaine du site Web.

Avec l’ESP32, pour vérifier la validité d’un serveur, vous pouvez charger n’importe lequel de ces certificats : certificat root, intermédiaire ou serveur.

Date d’expiration des certificats

Les certificats SSL/TLS ont une date d’expiration. Vous pouvez vérifier sur un navigateur la date d’expiration du certificat pour un serveur particulier. Le certificat du serveur a généralement une validité à court terme.

Ainsi, si vous souhaitez l’utiliser dans vos projets ESP32, vous devrez mettre à jour votre code assez fréquemment. Si vous souhaitez que votre code s’exécute pendant des années sans vous inquiéter, vous pouvez utiliser le certificat root du site Web, qui a généralement une validité de cinq à dix ans ou plus.

Obtenir un certificat de serveur

Il existe différentes manières d’obtenir le certificat du serveur. L’un des moyens les plus simples consiste à télécharger le certificat directement depuis votre navigateur. Vous pouvez aussi utiliser OpenSSL et obtenez toutes les informations de certificat dont vous avez besoin à l’aide de la ligne de commande (nous ne couvrirons pas cette méthode dans ce didacticiel).

Dans cette section, vous apprendrez comment obtenir le certificat du serveur. Nous utiliserons généralement le certificat root, mais vous pouvez utiliser n’importe lequel des autres certificats de la chaîne de certificats. Il vous suffit de connaître la date d’expiration du certificat.

Obtenir un certificat de serveur à l’aide de Google Chrome

Dans cette section, nous allons vous montrer comment obtenir le certificat d’un serveur à l’aide de Google Chrome (c’est le navigateur Web que nous utilisons le plus souvent). Les instructions pour les autres navigateurs Web devraient être similaires.

L’un des exemples que nous utiliserons plus tard consiste à envoyer une requête HTTPS au site Web howmyssl.com. Ainsi, à des fins de démonstration, nous allons vous montrer comment obtenir son certificat root. Il en est de même pour les autres sites Web.

Comment obtenir le certificat de sites Web à l’aide de Google Chrome ?

  1. Accédez au site Web pour lequel vous souhaitez obtenir le certificat.
  1. Cliquez sur l’icône du cadenas puis cliquez sur Afficher les détails de connexion.
obtenir un certificat ssl de site Web
  1. Ensuite, cliquez sur Afficher le certificat.
afficher le certificat google chrome
  1. Une nouvelle fenêtre ouvrira toutes les informations sur le certificat du site Web. Cliquez sur l’onglet Détails, assurez-vous de sélectionner le certificat root (c’est ce que nous recherchons dans cet exemple), puis cliquez sur Exporter…
détails du certificat ssl
  1. Sélectionnez un emplacement sur votre ordinateur pour enregistrer le certificat. Enregistrez-le au format par défaut : ASCII encodé en Base64, certificat unique (*.pem, .crt). Et c’est tout.

Vous pouvez double-cliquer sur le certificat pour vérifier ses détails, y compris la date d’expiration.

toutes les informations sur le certificat ssl

Ouvrez le certificat à l’aide du Bloc-notes ou d’un autre logiciel similaire. Vous devriez obtenir quelque chose de similaire comme indiqué ci-dessous.

bloc-notes de certificat

Nous devons convertir ceci en chaîne multiligne Arduino, afin que nous puissions l’utiliser dans notre esquisse. Fondamentalement, vous devez ajouter un  » au début de chaque ligne et un \n » \ à la fin de chaque ligne, sauf la dernière ligne où vous devez ajouter \n ». Ainsi, vous obtiendrez quelque chose comme indiqué ci-dessous :

chaîne de plusieurs lignes de certificat

Requêtes HTTPS avec l’ESP32

Maintenant que vous connaissez tous les principaux aspects importants des certificats et comment obtenir un certificat de serveur, voyons enfin comment effectuer des requêtes HTTPS sur l’ESP32 à l’aide du noyau Arduino. Nous couvrirons différentes méthodes en utilisant deux bibliothèques différentes : WiFiClientSecure et HTTPClient.

Requêtes HTTPS avec l'ESP32

Requêtes HTTPS ESP32 utilisant la bibliothèque WiFiClientSecure

Vous pouvez trouver un exemple simple montrant comment faire des requêtes HTTPS avec la bibliothèque WiFiClientSecure sur votre IDE Arduino.

Requêtes HTTPS ESP32 avec certificat

Assurez-vous d’avoir une carte ESP32 sélectionnée dans Outils > Carte. Ensuite, allez dans Fichier > Exemples > WiFiClientSecure > WiFiClientSecure.

Vous pouvez modifier le code suivant avec le certificat que nous avons obtenu des étapes précédentes, qui est valide jusqu’en 2035.

/*
  Complete project details: https://Raspberryme.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" \
  "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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;

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
}

Afficher le code brut

Cet exemple établit une connexion sécurisée avec le site Web www.howsmyssl.com et vérifie son certificat pour s’assurer que nous sommes connectés au serveur que nous attendons.

Si vous avez l’habitude de faire des requêtes HTTP avec l’ESP32 en utilisant la bibliothèque WiFiClient, cet exemple n’est pas très différent.

Comment fonctionne le code ?

Vous devez inclure la bibliothèque WiFiClientSecure.

#include <WiFiClientSecure.h>

Insérez vos informations d’identification réseau dans les lignes suivantes.

const char* ssid     = "REPLACE_WITH_YOUR_SSID";     // your network SSID (name of wifi network)
const char* password = "REPLACE_WITH_YOUR_PASSWORD"; // your network password

Insérez l’URL du serveur. Dans ce cas, nous ferons une demande à www.howsmyssl.com. Ce site Web renverra la qualité du SSL du client (dans ce cas, l’ESP32).

const char*  server = "www.howsmyssl.com";  // Server URL

Ensuite, vous devez insérer le certificat du serveur. Nous utilisons le certificat root.

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";

Créez un nouveau client appelé client à l’aide de WiFiClient secure.

WiFiClientSecure client;

Dans setup(), initialisez le Serial Monitor et connectez-vous à votre réseau.

//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);

La ligne suivante définit le certificat client à l’aide de la méthode setCACert() sur le client.

 client.setCACert(test_root_ca);

Ensuite, le client se connecte au serveur. Pour HTTPS, vous devez utiliser le port 443.

if (!client.connect(server, 443))
    Serial.println("Connection failed!");

Si la connexion réussit, nous pouvons effectuer la requête HTTP. Dans ce cas, nous faisons une requête GET. Notez que vous devez utiliser https:// avant l’URL à laquelle vous ferez une demande.

  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();

Enfin, nous obtenons et imprimons la réponse du serveur :

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);
    }

En fin de compte, nous fermons la connexion avec le client.

client.stop();

Dans cet exemple, nous effectuons la requête une seule fois dans setup(). La boucle () est vide, mais vous pouvez ajouter toutes les autres tâches dont vous avez besoin dans votre projet. Ou, selon l’application, vous pouvez faire la demande sur la boucle().

void loop() {
  // do nothing
}

En résumé, pour faire des requêtes HTTPS :

  • Inclure la bibliothèque WiFiClientSecure ;
  • Créez un client WiFiClientSecure ;
  • Utilisez le port 443 ;
  • Utilisez la fonction setCACert() pour définir le certificat client.
  • Utilisez https sur l’URL lors de la demande HTTPS.

Manifestation

Téléchargez le code sur votre tableau.

Ouvrez le moniteur série à un débit en bauds de 115200 et appuyez sur le bouton RST intégré.

Vous devriez obtenir quelque chose comme indiqué dans la capture d’écran suivante.

Exemple de moniteur série ESP32 WiFiClientSecure

Si vous faites défiler vers la droite, vous obtiendrez le résultat de la sécurité de la connexion. Vous devriez obtenir un « Probablement d’accord ».

Exemple de moniteur série ESP32 WiFiClientSecure

Requêtes HTTPS ESP32 sans certificat

Si vous souhaitez ignorer la vérification du certificat du serveur SSL, mais que vous souhaitez toujours avoir une communication cryptée, vous pouvez supprimer la ligne suivante :

 client.setCACert(test_root_ca);

Et ajoutez la ligne suivante avant de vous connecter au client :

client.setInsecure();

L’exemple complet se trouve ci-dessous.

/*
  Complete project details: https://Raspberryme.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
}

Afficher le code brut

Avec cet exemple, votre connexion est toujours cryptée, mais vous ne saurez pas si vous parlez au bon serveur. Ce scénario est utile à des fins de test.

Requêtes HTTPS ESP32 avec ensemble de certificats

Au lieu d’utiliser un seul certificat, vous pouvez utiliser un ensemble de certificats : une collection de certificats de confiance que vous pouvez charger dans votre carte. Ensuite, vous n’avez pas à vous soucier d’obtenir le certificat pour un serveur spécifique.

La bibliothèque WiFiClient fournit des informations sur l’utilisation d’un ensemble de certificats sur le lien suivant :

J’ai suivi toutes les instructions fournies et j’ai eu le problème suivant:

[  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

Si quelqu’un sait comment résoudre ce problème, veuillez le partager dans les commentaires ci-dessous.

Requêtes HTTP ESP32 utilisant la bibliothèque HTTPClient

La bibliothèque HTTPClient fournit un exemple simple montrant comment effectuer des requêtes HTTPS avec l’ESP32. Vous pouvez trouver l’exemple dans votre IDE Arduino. Tout d’abord, assurez-vous d’avoir sélectionné une carte ESP32 dans Outils> Carte. Ensuite, allez dans Fichier > Exemples > HTTPClient > BasicHttpsClient. Nous avons créé de nouveaux croquis basés sur cet exemple. Voir le code ci-dessous.

Requêtes HTTPS ESP32 avec certificat

L’esquisse suivante fait une demande à howsmyssl.com comme les exemples précédents mais utilise la bibliothèque HTTPClient. Il vérifie le certificat du serveur. Nous utiliserons le certificat root que nous avons obtenu lors des étapes précédentes.

/*
  Complete project details: https://Raspberryme.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" \
     "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\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);
}

Afficher le code brut

Comment fonctionne le code ?

Commencez par inclure les bibliothèques requises : WiFi.h, WiFiClientSecure.h et HTTPClient.h.

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>

Insérez vos identifiants réseau dans les lignes suivantes :

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Ensuite, vous devez ajouter le certificat du serveur. Nous utilisons le certificat root pour howsmyssl.com (voir les étapes précédentes).

const char* rootCACertificate = \
     "-----BEGIN CERTIFICATE-----\n" \
     "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\n" \
     "-----END CERTIFICATE-----\n";

Dans la configuration (), initialisez le moniteur série et connectez-vous au 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());
}

Dans la boucle (), créez un pointeur vers WiFiClientSecure appelé client.

 WiFiClientSecure *client = new WiFiClientSecure;

Définissez un client sécurisé avec le certificat à l’aide de la méthode setCACert() :

 client->setCACert(rootCACertificate);

Ensuite, créez une instance HTTPClient appelée https.

//create an HTTPClient instance
HTTPClient https;

Initialisez le client https sur l’hôte spécifié à l’aide de la méthode begin(). Dans ce cas, nous faisons une demande sur l’URL suivante : https://www.howsmyssl.com/a/check.

 if (https.begin(*client, "https://www.howsmyssl.com/a/check")) {  // HTTPS

Obtenez le code de réponse du serveur.

 int httpCode = https.GET();

Si le code de réponse est un nombre positif, cela signifie que la connexion a été établie avec succès, nous pouvons donc lire la charge utile de la réponse à l’aide de la méthode getString() sur l’objet https. Ensuite, nous pouvons imprimer la charge utile dans le moniteur série. Dans une application pratique, vous pouvez effectuer toutes les tâches dont vous avez besoin avec l’ESP32 en fonction de la charge utile reçue.

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);
    }
  }

Si le code de réponse est un nombre négatif, cela signifie que nous avons une erreur. Nous imprimerons le code d’erreur.

else {
   Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}

Enfin, fermez la connexion HTTPS à l’aide de la méthode end() :

https.end();

Cet exemple spécifique fait une demande toutes les deux minutes. Vous pouvez le modifier en fonction des exigences de votre projet.

  Serial.println("Waiting 2min before the next round...");
  delay(120000);

Manifestation

Vous pouvez modifier le niveau de débogage pour obtenir plus d’informations sur ce qui se passe dans le processus. Accédez à Outils > Niveau de débogage principal > Débogage. Ensuite, vous pouvez télécharger le code sur l’ESP32.

Après avoir téléchargé le code, ouvrez le moniteur série à un débit en bauds de 115200. Appuyez sur la carte RST intégrée pour commencer à exécuter le code nouvellement téléchargé.

Vous devriez obtenir quelque chose de similaire, comme indiqué dans l’image ci-dessous.

Requête HTTP de démonstration ESP32 avec charge utile de réponse

Si vous faites défiler vers la droite, vous obtiendrez le résultat de la sécurité de la connexion. Vous devriez obtenir un « Probablement d’accord ».

Requêtes HTTPS ESP32 sans certificat

Si vous souhaitez ignorer la vérification du certificat du serveur SSL, mais que vous souhaitez toujours avoir une communication cryptée, vous pouvez supprimer la ligne suivante :

 client.setCACert(test_root_ca);

Et ajoutez la ligne suivante avant de démarrer le client HTTP :

client.setInsecure();

L’exemple complet se trouve ci-dessous.

/*
  Complete project details: https://Raspberryme.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);
}

Afficher le code brut

Avec cet exemple, votre connexion est toujours cryptée, mais vous ne saurez pas si vous parlez au bon serveur. Ce scénario est utile à des fins de test.

Après avoir téléchargé cet exemple, voici ce que vous devriez obtenir :

Requête HTTPs de démonstration ESP32

Votre connexion est toujours cryptée, mais elle ignorera la vérification SSL.

Conclusion

Dans ce tutoriel, vous avez appris à faire des requêtes HTTPS avec l’ESP32. Vous avez également appris les concepts de base du protocole HTTPS et les certificats SSL/TLS.

Nous avons examiné des exemples avec les bibliothèques WiFiClientSecure et HTTPClient. Les exemples présentés sont les plus simples possibles afin que vous puissiez les modifier et les appliquer à vos propres projets. Vous avez appris à faire des requêtes HTTPS avec et sans vérification du certificat SSL/TLS.

Nous espérons que vous avez trouvé ce tutoriel utile. Nous avons l’intention de créer plus de tutoriels sur HTTPS et la communication sécurisée. Faites-nous savoir dans les commentaires ci-dessous ce que vous en pensez.

En savoir plus sur l’ESP32 avec nos ressources :

Merci d’avoir lu.

Cette vidéo vous emmène dans l’histoire de Raspberry Pi :

YouTube video

  • XTVTX 2 Pièces ESP32 cartes de développement ESP32S 2,4 GHz double mode WiFi + Bluetooth Dual Core Microcontrôleur Processeur intégré avec antenne ESP-32s RF AMP Filtre AP STA pour Arduino IDE
    Très faible consommation d'énergie, fonctionne parfaitement avec le Arduino IDE ESP32 cartes de développement Bluetooth double mode WiFi 2,4 GHz ESP32 Prend en charge trois modes : AP, STA, et AP STA L'ESP32 est sûr, fiable et évolutif pour une variété d'applications Microcontrôleur Bluetooth à double cœur intégré avec antenne ESP32s RF Filtre AP STA
  • Lot de 3 cartes de développement ESP32 DevKitC ESP32 ESP32-WROOM-32U WiFi Bluetooth pour Arduino IDE
    Lot de 3 cartes mères ESP32 DevKitC ESP32 ESP32-WROOM-32U pour Arduino IDE Consommation d'énergie ultra faible, fonctionne parfaitement avec l'Arduino IDE. ESP32 est sécurisé, fiable et évolutif pour une grande variété d'applications. Les développeurs peuvent connecter des périphériques à des câbles de pontage ou monter ESP32-DevKitC V4 sur une planche à découper. Câble d'ordinateur USB A / Micro USB B
  • ESP32 ESP32S Node-MCU-32S ESP-WROOM-32 Carte de développement avec WiFi Double Mode 2,4 GHz + Bluetooth processeur Double cœur pour Arduino
    🟠【Avantages】:Consommation d'énergie ultra-basse, compatible parfaitement avec l'IDE Arduino,Prise en charge de trois modes : AP, STA, AP+STA mode coexistence. 🟠【Stabilité】:ESP32 ESP-WROOM-32 antenne intégrée et filtre RF AMP pour une meilleure qualité de signal 🟠【Fonction】:La petite taille du module ESP32 permet de l'intégrer facilement dans d'autres produits.Supporte le protocole LWIP, Freertos 🟠【Compatible】:Compatible avec Arduino, Nodemcu, et MicroPython, peut être programmé avec l'IDE Arduino et Lua, peut s'adapter sur une planche à pain sans soudure, rend votre développement plus facile. 🟠【Sûre et Fiable】:ESP 32 La puce bimode Wifi et Bluetooth 2,4 GHz adopte la technologie 40nm à faible consommation d'énergie, qui présente la meilleure consommation d'énergie et la meilleure performance RF, et facile à étendre à diverses applications.