ESP32 wifi server + authentication protocol?

Hello All,

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:

  1. 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.

  2. Also both parties maintain a counter, to prevent a reply attack

  3. 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.

  4. 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))?

Thank you!

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 )

1 Like

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.

Recommended approach: HMAC + counter (or timestamp)

Use a shared secret key and compute an HMAC over the message and a counter:

HMAC = HMAC-SHA256(secret, payload || counter)

Send:

payload + counter + HMAC

On the receiver side:

  • Recompute the HMAC using the same secret
  • Compare it with the received HMAC
  • Reject if it doesn’t match
  • Also reject if the counter was already used (prevents replay attacks)

Why this works

  • Ensures the message is authentic (only someone with the secret can generate it)
  • Protects integrity (payload tampering is detected)
  • Prevents replay attacks via the counter

ESP32 side

ESP32 already supports HMAC-SHA256 via mbedTLS, so this is straightforward and lightweight.

Android / App Inventor limitation

If App Inventor doesn’t support HMAC directly, you can:

  • Use a small JavaScript crypto library via the Web component, or
  • Use an extension/plugin that exposes SHA/HMAC functions

Alternative (if HMAC is not feasible)

Use AES-128 in GCM mode (preferred) or CBC + HMAC. AES-GCM gives both encryption and authentication in one step.

Important

Avoid:

  • Custom hash/nonce constructions
  • XOR-based schemes
  • Plain SHA256(secret + data)

These are not secure and can be broken.

1 Like

Hello,

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. :slight_smile: If that doesn't work, I'll use the JS method.

Do you think it worth sharing the extension if I'm done?

Thank you!

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”.

So basically:

  • Send: payload + counter + HMAC(secret, payload + counter)
  • On receive: recompute and compare
  • Reject if it doesn’t match or if counter is reused

That gives you authentication + replay protection without needing HTTPS, and it’s lightweight enough for ESP32.

On the App Inventor side, yeah — either:

  • a small extension (best option), or
  • JS via Web component

And yes, definitely share the extension if you build it — that would be useful for a lot of people working with ESP32 + App Inventor

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.