This document details the exact architectural flow and cryptographic pipeline implemented in the Graphical Password Authentication (GPA) system.
- Request: Frontend sends
POST /api/auth/challengewith the user's identifier. - Nonce Generation: Backend generates a cryptographically secure 32-byte challenge ID (
secrets.token_urlsafe). - Grid Selection: Backend selects a random pool of 12 images from the master catalog.
- State Storage: The challenge and image pool are stored in Redis with a 300-second TTL.
- Recognition: User selects exactly 3 images from the 12-image grid.
- Recall: User clicks exactly 6 ordered points on the canvas.
- Submission: Frontend normalizes coordinates to
[0.0, 1.0]and submits the payload.
- Challenge Consumption: The 300s nonce is validated and immediately deleted to prevent replay attacks.
- Quantization: The normalized
[0,1]coordinates are mapped to a 4x4 virtual grid using a strict0.30tolerance, producing cell indices[0-15]. - Canonicalization:
- Image IDs are sorted and comma-separated (e.g.,
img_01,img_04,img_12). - Grid indices are pipe-separated (e.g.,
4|11|2|15|9|0). - The two strings are concatenated.
- Image IDs are sorted and comma-separated (e.g.,
- Salting & Pre-hashing:
- A random 16-byte salt is generated.
prehash = SHA3_256(canonical_string + salt)
- Final Key Derivation:
- The environment
GPA_PEPPERis appended to the pre-hash. final_hash = Argon2id(prehash + pepper)(Configured for 64MB memory, 2 iterations, 2 parallelism).
- The environment
- Encryption at Rest: The raw image selections are encrypted using AES-256-GCM (keyed via
GPA_MASTER_KEY) and stored as arecognition_blob. - Storage: The
identifier,final_hash,salt, andrecognition_blobare committed to PostgreSQL.
Identical to the registration flow. A fresh 300s nonce and randomized 12-image grid are generated.
The user selects 3 images and clicks 6 points. Simultaneously, the frontend BiometricsCollector passively records:
- Mouse velocity and acceleration.
- Click interval entropy.
- Interactions with invisible "honey pixel" trap coordinates.
- Challenge Consumption & Rate Limiting: Nonce is validated. Sliding-window rate limits (20 req / 10 min) are enforced.
- Behavioral Analysis:
- Rule Engine: Analyzes velocity variance, click entropy, and honey pixel hits.
- Risk Engine (ML): Feature vector passed to the Scikit-learn
IsolationForestmodel. - Drift Detection: Compares current behavior against the user's historical Welford Z-scores.
- If flagged as a bot: The system immediately shifts to generating a fake hash to stall the attacker.
- Database Lookup: The user record is retrieved. If not found, anti-enumeration fake-hashing engages.
- Cryptographic Verification:
- The submitted payload is quantized, canonicalized, and SHA3-prehashed using the stored salt.
Argon2id.verify()checks the resulting material against the stored database hash.
- Session Issuance: On success, a 15-minute JWT is issued, and a tamper-evident event is appended to the
AuditLog. - Constant-Time Padding: Regardless of success, failure, or bot detection, the
TimingGuardMiddlewaredelays the HTTP response to ensure a minimum processing time of ~180ms.
| Threat Vector | Mitigation Strategy |
|---|---|
| Credential Stuffing | Text passwords do not exist. Attacks cannot be ported from other breaches. |
| Offline Cracking | Server-side pepper + Argon2id memory hardness mathematically prevents GPU brute-forcing if the database leaks. |
| Replay Attacks | Redis enforces strict one-time consumption of challenge nonces. |
| User Enumeration | Timing guards and fake-hash computations ensure identical response profiles for valid and invalid usernames. |
| Automated Botnets | Continuous passive biometric evaluation and Isolation Forest anomaly detection. |