# ADR-003: Argon2id + Werkzeug-Kompatibilitätsschicht (pbkdf2 UND scrypt) **Datum:** 2026-07-15 · **Status:** Akzeptiert (ergänzt um scrypt nach Prod-Befund B4) ## Kontext Bestandskonten wurden von Werkzeug (Flask) gehasht. Zwangs-Passwort-Reset für den Produktiv-Mandanten war inakzeptabel. Werkzeug erzeugt je nach Version pbkdf2:sha256- ODER scrypt-Hashes (>= 3.0 Default: scrypt) — die Flask-Ära installierte ungepinnt, in Produktion lagen scrypt-Hashes. ## Entscheidung Neue Hashes: Argon2id (RustCrypto-Defaults). verify_password() erkennt Werkzeug-Formate (`pbkdf2:sha256:*` und `scrypt:n:r:p$salt$hex`), verifiziert in Konstantzeit und rehasht beim ersten erfolgreichen Login transparent auf Argon2id (schleichende Migration, kein Reset). ## Konsequenzen + Bestandslogins funktionieren unverändert; Bestand härtet sich selbst nach. − Werkzeug-Kompatibilitätscode bleibt, bis alle Konten migriert sind (prüfbar: `SELECT count(*) FROM users WHERE password_hash NOT LIKE '$argon2%'`). − Lehre: Der erste Wurf unterstützte nur pbkdf2 und fiel in Produktion auf (Login-Ausfall + Rate-Limit-Sperre). Hash-Kompatibilität ist künftig gegen reale Prod-Hash-Prefixe zu verifizieren (Forensik phase-010, Befund B4).