I’ve set up a working communication between an ESP32 HTTP server and App Inventor 2 Android. But I don’t want others to eavesdrop the communication or execute commands on the ESP32. Creating an HTTPS server on the ESP is not an easy thing to maintain, so I though I could create an authentication mechanism where both parties can validate if the request, or the reply comes from the party that were “paired” before, using a shared secret. I’m thinking on the followings:
In an appropriate safe moment, the shared secret can be generated on the Anroid side and transferred to the ESP32. Both parties store the shared secret.
Also both parties maintain a counter, to prevent a reply attack
Out of the payload, the counter and the shared secret, I’ll create a one-time “nonce” and send the current counter and the nonce together with the unencrypted payload.
The receiving party gets the counter and the payload, it has the shared secret so it generate do the same one-time “nonce”. It compares the generated nonce with the received nonce; if they match, that means the other party is trusted so the command can be executed. If the receiving party is the ESP, it can replay with a HTTP error 403. If the receiving party is the Android side, it can simply drop the data and treat the pairing as “broken”.
I’m looking for a hashing algorithm that I can implement on both the ESP32 and the Android. The ESP32 could do HMAC-SHA256, but I can’t see it easily possible on the Android side. I cannot implement something too complex at the ESP32 side, because the memory and Eeprom is quite limited (I use it for something else). Could you please propose something for me, that are relatively easy to implement, work with App Inventor 2 and ESP32, the footprint is light and it is not trivial to break (e.g. simply XOR of data, or other non-crypto solutions are not really demanded (only if there is no other way))?
wpa encryption should be ok to stop those who don’t have access to the wpa credentials ( and wifi is not that easy to sniff even for the “casual user” having access to the wpa credentials ).
If you want to add another layer of security, I’d choose a crypto algorithm for which you have an esp32 and a javascript library, es: aes-128 ( in ai2 use the web component to run the js library )
You’re on the right track with shared secrets and counters, but what you’re trying to build is essentially a custom crypto protocol — and that’s risky. Instead of generating your own “nonce” logic, you should use a standard construction that already solves this problem.
thank you both for the suggestions! The only problem with WPA is a “little” detail I didn’ mention. The default / fallback connectivity for the ESP32 is to use SoftAP. I have to disclose the credential for the softAP so the Android can connect and the user can set up a wifi connection that the ESP32 connects to. From that point, the ESP32 would connect to the wifi, but if it fails, it falls back to softAP mode. This should also work at places where no wifi is available, and for some users, softAP will be the only way to connect. And the credentials for that does not change, because the user needs a last resort connect method. That is why I'm looking for further security.
At first, I'll try to write an extension for that, because I've never tried. If that doesn't work, I'll use the JS method.
Do you think it worth sharing the extension if I'm done?
Yeah that makes sense — SoftAP as fallback changes things, so WPA alone isn’t enough here.
In your case, I’d still avoid building your own nonce/validation logic. The simplest solid solution is to keep your shared secret + counter idea, but use HMAC-SHA256 instead of a custom “nonce”.
This is sounds like a little nonsense to me. Why do you want to protect anything that runs on a softAP. I mean what does an ESP32 do without WiFi that has to be protected. No offense, it is a serious question. I understand if you use it through the internet, but what can happen in a small room connected to SoftAP? And even through internet… If you do not control your heating system or alarm with it, then meanningless.