ESP8266 HTTPS客户端 不校验证书指纹

  • A+
所属分类:Arduino ESP8266

ESP8266 HTTPS客户端 不校验证书指纹

为什么要这样做?

我们在请求公共API时大部分都是https,而ESP8266HTTPClient请求https需要服务器证书指纹才能连接,如果证书过期我们就需要修改代码里的证书指纹重新烧录。

什么时候不建议用这种方法

  • 涉及/传输任何类型的个人或敏感数据,例如密码,密钥,个人消息
  • 伪造的价值/信息可能会造成破坏-例如,在您长达2周的暑假期间,由于有人伪造了您用来控制它们的API而打开了您家中的所有取暖器,或由于伪造了交易所而通过“错误”出售所有比特币的机器人收到的费率
  • 原始的Arduino BasicHttpsClient示例(带有指纹)

    1. #include <Arduino.h>  
    2.   
    3. #include <ESP8266WiFi.h>  
    4. #include <ESP8266WiFiMulti.h>  
    5.   
    6. #include <ESP8266HTTPClient.h>  
    7.   
    8. #include <WiFiClientSecureBearSSL.h>  
    9. // Fingerprint for demo URL, expires on June 2, 2019, needs to be updated well before this date  
    10. const uint8_t fingerprint[20] = {0x5A, 0xCF, 0xFE, 0xF0, 0xF1, 0xA6, 0xF4, 0x5F, 0xD2, 0x11, 0x11, 0xC6, 0x1D, 0x2F, 0x0E, 0xBC, 0x39, 0x8D, 0x50, 0xE0};  
    11.   
    12. ESP8266WiFiMulti WiFiMulti;  
    13.   
    14. void setup() {  
    15.   
    16.   Serial.begin(115200);  
    17.   // Serial.setDebugOutput(true);  
    18.   
    19.   Serial.println();  
    20.   Serial.println();  
    21.   Serial.println();  
    22.   
    23.   for (uint8_t t = 4; t > 0; t--) {  
    24.     Serial.printf("[SETUP] WAIT %d...\n", t);  
    25.     Serial.flush();  
    26.     delay(1000);  
    27.   }  
    28.   
    29.   WiFi.mode(WIFI_STA);  
    30.   WiFiMulti.addAP("SSID""PASSWORD");  
    31. }  
    32.   
    33. void loop() {  
    34.   // wait for WiFi connection  
    35.   if ((WiFiMulti.run() == WL_CONNECTED)) {  
    36.   
    37.     std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);  
    38.   
    39.     client->setFingerprint(fingerprint);  
    40.   
    41.     HTTPClient https;  
    42.   
    43.     Serial.print("[HTTPS] begin...\n");  
    44.     if (https.begin(*client, "https://jigsaw.w3.org/HTTP/connection.html")) {  // HTTPS  
    45.   
    46.       Serial.print("[HTTPS] GET...\n");  
    47.       // start connection and send HTTP header  
    48.       int httpCode = https.GET();  
    49.   
    50.       // httpCode will be negative on error  
    51.       if (httpCode > 0) {  
    52.         // HTTP header has been send and Server response header has been handled  
    53.         Serial.printf("[HTTPS] GET... code: %d\n", httpCode);  
    54.   
    55.         // file found at server  
    56.         if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {  
    57.           String payload = https.getString();  
    58.           Serial.println(payload);  
    59.         }  
    60.       } else {  
    61.         Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());  
    62.       }  
    63.   
    64.       https.end();  
    65.     } else {  
    66.       Serial.printf("[HTTPS] Unable to connect\n");  
    67.     }  
    68.   }  
    69.   
    70.   Serial.println("Wait 10s before next round...");  
    71.   delay(10000);  
    72. }  

    修改后的HttpsClient示例(不带指纹)

    1. #include <Arduino.h>  
    2.   
    3. #include <ESP8266WiFi.h>  
    4. #include <ESP8266WiFiMulti.h>  
    5.   
    6. #include <ESP8266HTTPClient.h>  
    7.   
    8. #include <WiFiClientSecureBearSSL.h>  
    9. // Fingerprint for demo URL, expires on June 2, 2019, needs to be updated well before this date  
    10. // const uint8_t fingerprint[20] = {0x5A, 0xCF, 0xFE, 0xF0, 0xF1, 0xA6, 0xF4, 0x5F, 0xD2, 0x11, 0x11, 0xC6, 0x1D, 0x2F, 0x0E, 0xBC, 0x39, 0x8D, 0x50, 0xE0};  
    11.   
    12. ESP8266WiFiMulti WiFiMulti;  
    13.   
    14. void setup() {  
    15.   
    16.   Serial.begin(115200);  
    17.   // Serial.setDebugOutput(true);  
    18.   
    19.   Serial.println();  
    20.   Serial.println();  
    21.   Serial.println();  
    22.   
    23.   for (uint8_t t = 4; t > 0; t--) {  
    24.     Serial.printf("[SETUP] WAIT %d...\n", t);  
    25.     Serial.flush();  
    26.     delay(1000);  
    27.   }  
    28.   
    29.   WiFi.mode(WIFI_STA);  
    30.   WiFiMulti.addAP("SSID""PASSWORD");  
    31. }  
    32.   
    33. void loop() {  
    34.   // wait for WiFi connection  
    35.   if ((WiFiMulti.run() == WL_CONNECTED)) {  
    36.   
    37.     std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);  
    38.   
    39.     //client->setFingerprint(fingerprint);  
    40.     client->setInsecure();  
    41.   
    42.     HTTPClient https;  
    43.   
    44.     Serial.print("[HTTPS] begin...\n");  
    45.     if (https.begin(*client, "https://jigsaw.w3.org/HTTP/connection.html")) {  // HTTPS  
    46.   
    47.       Serial.print("[HTTPS] GET...\n");  
    48.       // start connection and send HTTP header  
    49.       int httpCode = https.GET();  
    50.   
    51.       // httpCode will be negative on error  
    52.       if (httpCode > 0) {  
    53.         // HTTP header has been send and Server response header has been handled  
    54.         Serial.printf("[HTTPS] GET... code: %d\n", httpCode);  
    55.   
    56.         // file found at server  
    57.         if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {  
    58.           String payload = https.getString();  
    59.           Serial.println(payload);  
    60.         }  
    61.       } else {  
    62.         Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());  
    63.       }  
    64.   
    65.       https.end();  
    66.     } else {  
    67.       Serial.printf("[HTTPS] Unable to connect\n");  
    68.     }  
    69.   }  
    70.   
    71.   Serial.println("Wait 10s before next round...");  
    72.   delay(10000);  
    73. }  

    请求GitHubAPI示例

    1. #include <Arduino.h>  
    2. #include <ESP8266WiFi.h>  
    3. #include <ESP8266HTTPClient.h>  
    4. #include <WiFiClientSecureBearSSL.h>  
    5.   
    6. void setup() {  
    7.   Serial.begin(115200);  
    8.   Serial.println(F("\n\r* * * ESP BOOT * * *"));  
    9.   Serial.println(F("WiFi begin!"));  
    10.   WiFi.mode(WIFI_STA);  
    11.   WiFi.begin("SSID""PASSWORD");  
    12.   
    13.   while (WiFi.status() != WL_CONNECTED) {  
    14.     delay(500);  
    15.     Serial.print(".");  
    16.   }  
    17.   
    18.   Serial.println(F("\n\rWiFi connected!"));  
    19. }  
    20.   
    21. void TestHttpsAPI() {  
    22.   std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);  
    23.   client->setInsecure();  
    24.   HTTPClient https;  
    25.   
    26.   if (https.begin(*client, "https://api.github.com/")) {  // HTTPS  
    27.     Serial.println("[HTTPS] GET...");  
    28.     int httpCode = https.GET();  
    29.   
    30.     // httpCode will be negative on error  
    31.     if (httpCode > 0) {  
    32.       // HTTP header has been send and Server response header has been handled  
    33.       Serial.printf("[HTTPS] GET... code: %d\n", httpCode);  
    34.       // file found at server?  
    35.       if (httpCode == HTTP_CODE_OK) {  
    36.         Serial.println(String("[HTTPS] Received: ") + https.getString());  
    37.       }  
    38.     } else {  
    39.       Serial.printf("[HTTPS] GET... failed, error: %s\n\r", https.errorToString(httpCode).c_str());  
    40.     }  
    41.   
    42.     https.end();  
    43.   } else {  
    44.     Serial.printf("[HTTPS] Unable to connect\n\r");  
    45.   }  
    46. }  
    47.   
    48. void loop() {  
    49.   TestHttpsAPI();  
    50.   Serial.println("Wait 20s before next round to not get banned on API server...");  
    51.   delay(20000);  
    52. }  

    参考资料

  • Simple ESP8266 HTTPS client without verification of certificate fingerprint
  • HttpClient: HTTPS request without specifying certificate fingerprint?
  • 钰玺

    发表评论

    :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: