Demo 29: How to use HTTPS in Arduino ESP32 - IoT Sharing

Hot

Thursday, August 24, 2017

Demo 29: How to use HTTPS in Arduino ESP32

1. Introduction
In this tutorial I will show you how to use HTTPS for secure communication with server.
Figure: HTTP vs HTTPS
How it work?
In order to understand more clear, you should read about SSL&TLS and HTTPS. Here are some main points:
- HTTPS refers to use of ordinary HTTP over an encrypted SSL (Secure Sockets Layer) or TLS (Transport Layer Security) connection.
- TLS was introduced in 1999 as a new version of SSL and was based on SSL 3.0. 
- A concept called SSL/TLS certificate which is used to establish a SSL/TLS connection. SSL/TLS certificates use a key pair (a public and private key) to encrypt/decrypt data before exchanging it. So certificates are not dependent on protocols. It means when replacing SSL by TLS, the certificate is not change.
Figure: SSL/TLS certificate content
- The HTTPS message is encrypted, including the headers, and the request/response payload.
- The process before exchanging data is called SSL handshake. You can refer here.
- SSL/TLS Certificates need to be issued by a trusted Certificate Authority (CA). Client devices (browsers, OS, ... ) maintains list of trusted CA root certificates so that they can compare with server certificates in SSL handshake phase. 
- We also have Self-Signed SSL Certificate which is created by own self. It is considered insecure. It can be generated using openssl tool.
- In order to get certificate of a website that we want to establish a HTTPS connection. We will use openssl tool.
- You can install this tool for:
Ubuntu: sudo apt-get install openssl
CenOS ReadHat: yum install openssl
Windows: you can refere here
- In this demo we will create a simple HTTPS request from ESP32 client to "https://www.howsmyssl.com/a/check" (this site is used to check HTTPS connection) and print the response to Terminal.   
2. Software
- ESP32 using mbedTLS for SSL handshake phase. It is wrapped under WiFiClientSecure class.
- We create an instance of WiFiClientSecure:
WiFiClientSecure client;
and then we call method: client.setCACert(content_of_certificate) to point to SSL/TLS certificate for SSL handshake phase. Then we call a set of functions to form a HTTPS request:
client.println("GET https://www.howsmyssl.com/a/check HTTP/1.0");
client.println("Host: www.howsmyssl.com");
client.println("Connection: close");
Finally, we get the response from server using:
client.available(): to check whether server response data or not.
client.read(): to read response data from server.
In order to get the SSL/TLS certificate of "https://www.howsmyssl.com/a/check" we will use openssl tool above. From command line typing:
openssl s_client -showcerts -connect www.howsmyssl.com:443
Figure: Choose the certificate that contains the Signature Trust line
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <WiFiClientSecure.h>

const char* ssid     = "your-ssid";     // your network SSID 
const char* password = "your-password"; // your network password

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

/* use 
openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null 
to get this certificate */
const char* ca_cert = \ 
"-----BEGIN CERTIFICATE-----\n" \ 
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \ 
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \ 
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \ 
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \ 
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \ 
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \ 
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \ 
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \ 
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \ 
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \ 
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \ 
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \ 
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \ 
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \ 
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \ 
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \ 
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \ 
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \ 
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \ 
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \ 
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \ 
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \ 
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \ 
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \ 
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \ 
"-----END CERTIFICATE-----\n";

/* create an instance of WiFiClientSecure */
WiFiClientSecure client;

void setup() {
    Serial.begin(115200);

    WiFi.begin(ssid, password);

    /* waiting for WiFi connect */
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(100);
    }

    Serial.print("Connected to ");
    Serial.println(ssid);

    /* set SSL/TLS certificate */
    client.setCACert(ca_cert);

    Serial.println("Connect to server via port 443");
    if (!client.connect(server, 443)){
        Serial.println("Connection failed!");
    } else {
        Serial.println("Connected to server!");
        /* create 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();

        Serial.print("Waiting for response ");
        while (!client.available()){
            delay(50); //
            Serial.print(".");
        }  
        /* if data is available then receive and print to Terminal */
        while (client.available()) {
            char c = client.read();
            Serial.write(c);
        }

        /* if the server disconnected, stop the client */
        if (!client.connected()) {
            Serial.println();
            Serial.println("Server disconnected");
            client.stop();
        }
  }
}

void loop() {
}
3. Result
 Figure: Request and response from server

3 comments:

sheela rajesh said...

Nice blog post your gave for us. I heartfully thank you and i request you to add more informations like this in future.
JAVA Training in Chennai
JAVA Training in Tambaram
IOS Training in Chennai
Big data training in chennai
Python Training in Chennai
Selenium Training in Chennai
JAVA Training in Chennai
Java Training in Tambaram

Selvamani1991 said...
This comment has been removed by the author.
Selvamani1991 said...

ESP32-Mqtt was not connected using Azure SSL Certificate
I am using the below code for connecting with ssl certificate was not working.
#include
const char* ssid = "xxx"; // your network SSID (name of wifi network)
const char* password = "xxx"; // your network password
const char* server = "xxx.azure-devices.net"; // Server URL
const char* test_root_ca=
"-----BEGIN CERTIFICATE-----\n"

"-----END CERTIFICATE-----\n";

// You can use x.509 client certificates if you want
const char* test_client_key =
"-----BEGIN RSA PRIVATE KEY-----\n"

"-----END RSA PRIVATE KEY-----\n"; //to verify the client

const char* test_client_cert =
"-----BEGIN CERTIFICATE-----\n"

"-----END CERTIFICATE-----\n"; //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, 8883)){
Serial.println("Connection failed!");
}
else {
Serial.println("Connected to server!");
}
}
void loop() {
// do nothing
}

Thường mất vài phút để quảng cáo xuất hiện trên trang nhưng thỉnh thoảng, việc này có thể mất đến 1 giờ. Hãy xem hướng dẫn triển khai mã của chúng tôi để biết thêm chi tiết. Ðã xong