How to create SSL Certificates for Local Blynk Server on Windows 7?

I’m not exactly sure why you would need client certificates, but in larger enterprise or secure enviroments I can imagine each client (wether it be a phone or the hardware) is equipped with a certificate so the server knows its origins.

I’d just skip the certificate check to see if your script works. I’ve always found certificates to be a pain in the a$$ (and I’m a security/network engineer…).

I always thought that Chrome offered to show you the certificate details including fingerprint if you clicked the green padlock but it seems to have stopped working for me. Still working in Firefox though.

@Lichtsignaal

Costas I can still find the fingerpring SHA1 from chrome and also from firefox. The problem is it still doesn’t seem to work when I use it. ;-( Did you get it working ? and also did you get SSL working from wemos to your local Blynk server ? - if so is your certificate signed by a CA ?

I also tried using it to form a SSL connection between wemos and local blynk server by modifying “BlynkSimpleEsp8266_SSL.h” (see code snippet below that i modifed) BUT I found that my sketch would fail to connect to the local blynk server. When I use the provided BLYNK_DEFAULT_FINGERPRINT and connected to Blynk-cloud server it worked but not when I connected to my local Blynk server with my own FINGERPRINT.

@Dmitriy (perhaps you can provide some insight) Is it because my certificate needs to approved by a CA ? (this is the only thing I can think of) - anyone else in the community got this working ?

/**
 * @file       BlynkSimpleEsp8266_SSL.h
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Jan 2016
 * @brief
 *
 */

#ifndef BlynkSimpleEsp8266_SSL_h
#define BlynkSimpleEsp8266_SSL_h

#ifndef ESP8266
#error This code is intended to run on the ESP8266 platform! Please check your Tools->Board setting.
#endif

// #define BLYNK_DEFAULT_FINGERPRINT "FD C0 7D 8D 47 97 F7 E3 07 05 D3 4E E3 BB 8E 3D C0 EA BE 1C"  // for blynk-cloud
#define BLYNK_DEFAULT_FINGERPRINT "58 20 11 21 c1 0f a8 eb 7a da 25 2c 7a 7a 7d 7e 7e d2 47 fb"  // my local server [does not connect - I copied this FINGERPINT from my own certificate]

Extract of my sketch:

#define BLYNK_PRINT Serial
// #define BLYNK_DEBUG

// #include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

//needed for library
#include <ESP8266WebServer.h>
#include <DNSServer.h>
// #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>

// #include <BlynkSimpleEsp8266.h>
#include <BlynkSimpleEsp8266_SSL.h>

#include <SimpleTimer.h>
#include <ArduinoOTA.h>
#include <WiFiClientSecure.h>



#define vPIN_localORcloud_server 127

// Pins for WEMOS D1 mini and presume D1 R2

  #define D0  16
  #define D1  5
  #define D2  4
  #define D3  0
  #define D4  2
  #define D5  14
  #define D6  12
  #define D7  13
  #define D8  15
  #define RX  3
  #define TX  1



// select wich pin will trigger the configuraton portal when set to LOW
// ESP-01 users please note: the only pins available (0 and 2), are shared 
// with the bootloader, so always set them HIGH at power-up
#define TRIGGER_PIN D4



// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).

char auth_local_server[] = "xxxx"; // on mars000 local server 192.168.0.251 fileserver1


// setup for https calls 
const int httpsPort = 9443;

const char* host_fileserver1 = "192.168.0.251";
// Use web browser to view and copy
// SHA1 fingerprint of the certificate

const char* fingerprint_fileserver1 = "‎‎58 20 11 xx c1 0f a8 xx 7a da xx 2c 7a xx 7d 7e 7e xx 47 fb"; //copied from my certificate assigned to my local Blynk server (fileserver1)


// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxx";
char pass[] = "xxx";

SimpleTimer timer;
// Attach virtual serial terminal to Virtual Pin V8
WidgetTerminal terminal(V8);

bool cloud_server_active = false;
bool local_server_active = true;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("\n Starting");

  pinMode(TRIGGER_PIN, INPUT);
  int waittime = millis() + 10000;
  bool x = true;


 WiFi.begin(ssid, pass);          // use this code if we want to hardwire an access point
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (waittime < millis()) { break; }
  }
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());  

  Blynk.config(auth_local_server, IPAddress(192,168,0,251));

and here the serial output:

�
 Starting
.......
WiFi connected
IP address: 
192.168.0.40
[12944] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.4.3 on Arduino

Filename: https_blynk_API_example_code_mdv1
V1 19Feb2017 11:09
Blyn.connected is FALSE
[24956] Connecting to 192.168.0.251
[25275] Certificate doesn't match
[26957] Login timeout
failed to reconnect to Blynk

@mars we use self signed certificates, free Let’s Encyrpt certificates (renewable every 3 months) and paid for certificates (renewable annually).

The only fingerprint work we have done in earnest related to Google servers.

I will take a look at your details when I have time but meanwhile I will leave you with this puzzle.

"‎AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA";  // invalid certificate
"AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA";  // valid certifcate

Why?

why ? – I can’t work out the riddle :joy_cat:

I’ll leave the puzzle running until someone works it out.

I have made it as easy as possible compared with real world fingerprints.

the only reason I can see if because you can only have ONE unique fingerpint therefore the other must be invalid if one if valid.

Nope.

Maybe it doesn’t depend on the certificate itself… so the same certificate could be OK or NOK?
It must be something else (somewhere) to validate the certificate…

maybe its a question of TRUST - both certificates are the same but if one is NOT TRUSTED then its invalid.

No, the problem is as you see it, no external forces involved.

@mars my WeMos connects ok with BlynkSimpleEsp8266_SSL.h and Let’s Encrypt fingerprints.

Is your local server just local or accessible via the internet?

I have two. One that is local within my own intranet and another that is accessible from the internet.
I assume your certificates are signed by a trusted 3rd party (being yourself I assume if you use Let’s Encrypt) ? i.e. when trying to access your local server using https via chrome or firefox the browser does not throw exceptions to indicate the https is broken or not secure ?

Yes the “3rd party” is yourself with Let’s Encrypt and there are no warnings in web browsers. You just need a domain to go with the server.

My puzzle is actually very significant for anyone working with fingerprints.

Aside from the fact that you mispelt certificate in the valid one’s comments :wink:

Here is my guess, not based on knowledge persay, but deductive reasoning, and since one of these things is not like the other… it is rejected <— that’s a racist certificate reader :stuck_out_tongue: thus, I start looking for the hidden differences.

Anyhow… based on the developer tools in Chrome (which I only know about as my fumblefinger typing somehow keeps bringing it up :unamused: ) there is the invisible &lrm or left-to-right mark (LRM) character in the invalid cert. Something which word processors like MS Word may interject without? a user’s knowledge, due to written language translation or scripting direction? (I also see a double quote at the beginning, but not sure if that is part of the developer display or somehow another strange character input).

Basicly it is not clean ASCII or text, and will cause the all seeing authorising computer to cough up a hairball

nice work Gunner !
Now we await notification and adjudication from the “all seeing” Costas :wink:

Spot on @Gunner, very well done. I posted about the problem on GitHub but I wasn’t quite as eloquent as you and I incorrectly blamed a well known fingerprint checking site for adding the invisible character. Turns out it can be added if you swipe the fingerprint from your browser.

The GitHub thread is at HTTPS POST request to api returns -1 response (ssl) · Issue #2834 · esp8266/Arduino · GitHub and as I wrote at the time I had been doing some fingerprint work (Google Sheets) just a couple of days before the GitHub user posted his problem.

I too struggled for hours when working with a known Google fingerprint but some debugging tools built in to the ESP said the error was the first character of the fingerprint. I was amazed when I entered a backspace at the start of the fingerprint and it removed the invisible character.

So always look for the invisible character at the start of the fingerprint.

One other tip is to use Generic ESP board setting not WeMos when debugging this kind of issue. The ESP debugging feature is only available for the generic board setting.

@mars I think there is a fix for your problem, more to follow.

awesome !
Well I went back to my sketch and indeed I did a back space and there was an invisible character as I was required to backspace twice to get rid of it ! [thank you for that valuable tip]
I re-compiled the sketch but dang-it its still saying “certificate does not match” - i double checked it with firefox to be sure I had correct numbers.

This stuff is not easy to get working ;-(

With Chrome 56 Google have removed the direct access to the certificate.
It’s now in the security tab when using the Developer console.

@mars you might have already worked this out by now if you have looked at the libraries but I’ll post it anyway. In the sketch below with server as somedomain.com the SSL connection with fingerprint check is fine. When the server is changed to the IP address for the domain it will not connect and with full ESP debugging you will see:

[hostByName] Host: 10.10.10.10 is a IP!

Not grammatically correct but a debug message nonetheless.

// DomainAndIP.ino    22 Feb 2017 Costas http://community.blynk.cc/t/how-to-create-ssl-certificates-for-local-blynk-server-on-windows-7/2828/39
#define BLYNK_PRINT Serial          // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266_SSL.h> // 8441 is SSL port and 8442 is TCP port
#define USE_SERIAL Serial           // Debug ESP as generic board
#define BLYNK_DEFAULT_FINGERPRINT "AA ......AA" // ensure no invisible characters in the fingerprint

char auth[]     = "xxxxxxxxxxxxxxx";
char ssid[]     = "xxxxxxxxxxxxxxx";
char pass[]     = "xxxxxxxxxxxxxx";
char server[]   = "somedomain.com";
//char server[] = "10.10.10.10";

void setup()
{
  USE_SERIAL.setDebugOutput(true);  // Ensure the corresponding define statement is available
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass, server, 8441, BLYNK_DEFAULT_FINGERPRINT);
}

void loop()
{
  Blynk.run();
}

BlynkSimpleEsp8266_SSL.h checks the fingerprint for the domain with:

if (fingerprint && !this->client->verify(fingerprint, this->domain)) {
 // ..........................
}

The [hostByName] Host: 10.10.10.10 is a IP! message doesn’t come from Blynk and is part of the core ESP libraries. The expectation is for a domain name to have it’s fingerprint checked rather than an IP address but I have seen IP addresses validated.

More to follow…