Unable to connect https protocol with ESP8266 using WifiClientSecure

泪湿孤枕 提交于 2020-01-16 04:09:05

问题


I'm trying to get ESP8266 position by unwiredlabs. I followed with this introduction. This is my arduino code:

#include <ESP8266HTTPClient.h>
#include  <ArduinoJson.h>
#include "ESP8266WiFi.h"

char myssid[] = "Your wifi/hotspot name";
char mypass[] = "Your password";

const char* Host = "www.unwiredlabs.com";
String endpoint = "/v2/process.php";

String token = "d99cccda52ec0b";

String jsonString = "{\n";

double latitude = 0.0;
double longitude = 0.0;
double accuracy = 0.0;

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

    // Set WiFi to station mode and disconnect from an AP if it was previously connected
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    Serial.println("Setup done");

    // We start by connecting to a WiFi network
    Serial.print("Connecting to ");
    Serial.println(myssid);
    WiFi.begin(myssid, mypass);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println(".");
}

void loop() {
    char bssid[6];
    DynamicJsonBuffer jsonBuffer;

    // WiFi.scanNetworks will return the number of networks found
    int n = WiFi.scanNetworks();
    Serial.println("scan done");

    if (n == 0 ) {
        Serial.println("No networks available");
    } else {
        Serial.print(n);
        Serial.println(" networks found");
    }

      // now build the jsonString...
      jsonString = "{\n";
      jsonString += "\"token\" : \"";
      jsonString += token;
      jsonString += "\",\n";
      jsonString += "\"id\" : \"saikirandevice01\",\n";
      jsonString += "\"wifi\": [\n";
      for (int j = 0; j < n; ++j) {
          jsonString += "{\n";
          jsonString += "\"bssid\" : \"";
          jsonString += (WiFi.BSSIDstr(j));
          jsonString += "\",\n";
          jsonString += "\"signal\": ";
          jsonString += WiFi.RSSI(j);
          jsonString += "\n";
          if (j < n - 1) {
              jsonString += "},\n";
          } else {
              jsonString += "}\n";
          }
      }
      jsonString += ("]\n");
      jsonString += ("}\n");
      Serial.println(jsonString);

      WiFiClientSecure client;

      //Connect to the client and make the api call
      Serial.println("Requesting URL: https://" + (String)Host + endpoint);
      if (client.connect(Host, 443)) {
          Serial.println("Connected");
          client.println("POST " + endpoint + " HTTP/1.1");
          client.println("Host: " + (String)Host);
          client.println("Connection: close");
          client.println("Content-Type: application/json");
          client.println("User-Agent: Arduino/1.0");
          client.print("Content-Length: ");
          client.println(jsonString.length());
          client.println();
          client.print(jsonString);
          delay(500);
      }

      //Read and parse all the lines of the reply from server
      while (client.available()) {
          String line = client.readStringUntil('\r');
          JsonObject& root = jsonBuffer.parseObject(line);
          if (root.success()) {
              latitude    = root["lat"];
              longitude   = root["lon"];
              accuracy    = root["accuracy"];

              Serial.println();
              Serial.print("Latitude = ");
              Serial.println(latitude, 6);
              Serial.print("Longitude = ");
              Serial.println(longitude, 6);
              Serial.print("Accuracy = ");
              Serial.println(accuracy);
          }
      }

      Serial.println("closing connection");
      Serial.println();
      client.stop();

      delay(5000);
}

When code had been flashed to esp8266, it showed that could not to connect to https://www.instructables.com/v2/process.php.

ESP serial output:

... // some initial setup string
Requesting URL: https://unwiredlabs.com/v2/process.php
// if connected, "connected" was printed here, but not
closing connection

Then, I tried to use url https://unwiredlabs.com/v2/process.php on chrome browser. This is message:

{
status: "error",
message: "Invalid request",
balance: 0,
help: "Check for misplaced commas and use double quotes to encapsulate strings"
}

This proved that this url existed, but when i tried on Postman, it showed:

Then, I turned off SSL certificate verifycation on Postman. It responsed with a 403 Forbidden error. So i think the reason caused problem is SSL certificate verifycation of WifiClientSecure.

Anyone can help?


回答1:


SSL - at least the way this code is trying to use it - requires the Fingerprint of the site you're trying to connect to. The code needs to tell its client object the fingerprint of the site before trying to connect to that site.

Step 1: manually retrieve the fingerprint from the site: I browsed to https://www.unwiredlabs.com in Chrome and copied the site cerficate, then used openSSL in git bash on Windows to extract the fingerprint:

openssl x509 -noout -fingerprint -sha1 -inform pem -in certificate-file.cer > fingerprint.txt

I then edited the resulting fingerprint.txt file, replacing each ':' with a space.

Search the net for details on how to copy the cite certificate using Chrome, or whatever browser you're using.

Step 2: edit the code to add the fingerprint to the Sketch: I added the constant 'sslFingerprint', and added a call to client.setFingerprint() just before calling client.connect().

I then removed the code unrelated to connecting to the site, creating an example Sketch that illustrates a successful connection to unwiredlabs.com:

#include <ESP8266HTTPClient.h>
#include "ESP8266WiFi.h"

// The SSL Fingerprint of https://www.unwiredlabs.com
// Certificate expires ‎October ‎9, ‎2020
const char *sslFingerprint
  = "C3 3E 2F 21 CB 15 4E 02 D5 27 E5 F6 EF FB 31 AE 91 51 A3 5D";

char myssid[] = "yourWiFiSSID";
char mypass[] = "yourWiFiPassword";

const char* Host = "www.unwiredlabs.com";
String endpoint = "/v2/process.php";

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

  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  Serial.println("Setup done");

  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  Serial.println(myssid);
  WiFi.begin(myssid, mypass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(".");
}

void loop() {
  WiFiClientSecure client;

  //Connect to the client and make the api call
  Serial.println("Requesting URL: https://" + (String)Host + endpoint);
  client.setFingerprint(sslFingerprint);
  if (client.connect(Host, 443)) {
    Serial.println("Connected");
  }
  Serial.println("closing connection");
  Serial.println();
  client.stop();

  delay(5000);
}

When run on a Sparkfun ESP8266 Thing Dev board, the Sketch produces this output:

......
Requesting URL: https://www.unwiredlabs.com/v2/process.php
Connected
closing connection


来源:https://stackoverflow.com/questions/59005181/unable-to-connect-https-protocol-with-esp8266-using-wificlientsecure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!