BioFin
Biometric customer verification for a commercial bank
The question
Can a Windows-only vendor scanner driver be rebuilt so an Android field agent produces encrypted prints the bank's own decryption path accepts, byte for byte?
A biometric customer-verification platform integrated with the bank's core banking system and national ID verification, spanning a Laravel backend, a Windows scanner client, an encryption service, and an Android app for field agents.
- 3
- Clients
- AES + RSA
- Encryption
- VAPT cleared
- Security review
capture → WSQ → AES → RSA → the bank's core
Problem
The bank needed to verify customers by fingerprint at the point of service and in the field, match them against its own records and the national ID database, and do it without ever letting a raw fingerprint travel or rest unencrypted. The vendor scanner driver bundled capture, compression, and encryption into one Windows-only DLL, which made a mobile field workflow impossible.
Constraints
- Fingerprints are regulated biometric data. Nothing may be logged, cached, or transmitted in the clear.
- The bank's driver produces encrypted WSQ blobs in a proprietary envelope. Output from any new client had to be byte-compatible.
- Field agents work on Android with USB scanners; branch staff work on Windows. Both had to feed one backend.
- A third-party VAPT would gate the release.
Architecture
Three clients, one backend, one encryption service.
- Laravel backend with fifteen modules: onboarding drafts, verification, NID checks against Election Commission data, core-banking lookups over Oracle, notifications, audit logs, role-based access, and reporting.
- Windows encryption service (.NET Framework 4.8) that wraps the vendor DLL via reflection, performs raw-to-WSQ compression and AES/RSA envelope encryption, binds to localhost only, and writes metadata-only audit logs. Byte-for-byte identical output to the scanner driver.
- Android field-agent app (Kotlin, Jetpack Compose) driving SecuGen Hamster Pro 20 scanners over USB, with FLAG_SECURE everywhere, in-memory-only credentials, and R8 hardening.
- Windows desktop client (C#/.NET WinForms) for branch use, exposing a localhost HTTP API so the browser-based console can capture from a USB scanner.
What I built
I designed the system, wrote the encryption service and the desktop client, led the Android app, and built the backend modules for verification and NID integration. I reverse-engineered the driver's two-stage pipeline so the new service could produce output the bank's own decryption path accepts.
Outcome
All findings from the third-party VAPT were remediated, including debug-build artefacts, receiver export flags, cleartext policy, and task hijacking. The Android app ships privately through Managed Google Play with dependency locking for the bank's SBOM scans. The platform is in production.
Connections
Other work that sits in some of the same fields. The overlap is what the map draws.