Why
Most DIY fingerprint projects I've seen use a ready-made module that does the matching itself and talks to the ESP over a plain, unauthenticated UART. It's relatively easy to get access to the wiring and tell the ESP that "match is OK". A few modules do encrypt that link, but the key sits in the ESP's flash, and the same ESP still opens the door, so owning the ESP still means owning the door.
This project turns that around: the device in front of the door is deliberately dumb.
The idea
- The sensor is a bare FPC1020 capacitive sensor. It has no matching logic, no templates. It only produces a 192×192 image at 508 dpi.
- The ESP detects a finger, captures a frame, and uploads it to the server over Wi-Fi. That's all it does. It never decides anything.
- The server extracts the minutiae, matches them (SourceAFIS), and makes the decision.
- Home Assistant gets the result from the server (not from the device) and owns the access policy.
Threat model
I assume the device is physically reachable: it hangs outside, meaning it can be unplugged, replaced, opened, or have its cable and Wi-Fi intercepted.
What an attacker gets by compromising the device:
- the ability to submit images to the API, and to see the raw frames of whoever touches the sensor
- but not the things that actually make the decision: no templates, no names, no "granted" flag to flip. The server sends the verdict to Home Assistant itself, and the device only gets a vibration/LED hint for local feedback.
With a ready-made module, the attack takes a minute: open the case, connect to the sensor wires, send a fake "match". Here that doesn't work, because there is nothing to impersonate. The attack becomes a multi-step one:
- Get physical access and either tap the SPI bus or reflash the ESP to collect frames of legitimate touches.
- Come back (or connect remotely, if you have the token) and replay one of the collected frames.
This isn't impossible, but it takes time and preparation, and the measures below are meant to make it even harder.
What the design does about it
The server-side parts are planned, not built yet.
- Tamper switch. Opening the case triggers an alert, and Home Assistant stops reacting to the server's events until a manual reset is done. A device_offline alert that lasts longer than the grace period does the same, so unplugging the device doesn’t bypass it.
- Encrypted transport. Frames travel over TLS with a pinned server certificate, so someone sniffing the Wi-Fi sees neither the images nor the device token.
- Duplicate detection (an idea so far). Two real touches never give identical pixels. The server would reject exact copies of earlier frames, and flag frames whose minutiae are suspiciously close to an earlier one. Whether this works as I expect still has to be verified on real data.
- Policy in Home Assistant (optional, may not make it in). A fingerprint is one factor, not the whole decision. Automations could require something the device can’t fake alone, e.g., a phone nearby.
- Rate limiting and alerts. Bursts of no_match, invalid tokens, and unusual activity all raise alerts.
- Revocable device token. It can only submit frames, and the server drops the connection as soon as it’s revoked. The device is meant to sit on an IoT VLAN that reaches only the server.
- Encryption at rest on the server. Both the raw images and the minutiae templates are encrypted in the database, with a key kept outside the data volume. Fingerprints are biometrics: unlike a password, you can’t change them after a leak.
What remains
- Replay of frames the device has already seen. A fully compromised ESP can resend them. Duplicate detection and the policy make this expensive, but not impossible. A real fix needs trusted hardware (a secure element), which version 1 doesn't have.
- Secrets in the flash. The Wi-Fi PSK and the device token can be read by someone who takes the device. Flash encryption and secure boot can lock this down, but they make ESPHome OTA...
strange.rand