// projekt ·
Desktop-App zur Passwortverwaltung
Eine lokale Passwort-App, um die Grundlagen der Desktop-Sicherheit zu lernen. Stack: JavaFX, MySQL, JUnit.
Rolle: Privatprojekt · Jahr: 2023 - 2024 · Status: archiviert
kurz: Ein Passwortmanager für den Desktop in JavaFX, gebaut, um den Umgang mit Zugangsdaten richtig zu lernen. Das Login-Passwort wird mit BCrypt gehasht. Gespeicherte Website-Passwörter werden mit AES-256-GCM verschlüsselt, mit einem Schlüssel aus dem Login-Passwort, also liegen sie nie im Klartext in der Datenbank.
Problem
Ein Passwortmanager hat zwei Arten von Geheimnissen, und sie brauchen gegensätzliche Behandlung. Das Login-Passwort muss nur geprüft, nie zurückgelesen werden. Gespeicherte Website-Passwörter müssen später angezeigt und kopiert werden. Wer alles hasht, hat einen nutzlosen Tresor. Wer alles mit einem Schlüssel neben den Daten verschlüsselt, hat die Datenbank als einziges Schloss.
Rahmenbedingungen
- Mehrere Nutzer, eine MySQL-Datenbank. Wer nur die Datenbank hat, darf fremde gespeicherte Passwörter nicht lesen können.
- Der Schlüssel darf nicht gespeichert werden. Er muss aus etwas kommen, das nur der Nutzer weiß.
- Bestehende Zeilen. Einträge von vor der Verschlüsselung müssen weiter laden.
- Die Desktop-Oberfläche bleibt reaktionsfähig, während sie auf die Datenbank wartet.
Entscheidungen
- BCrypt für das Login-Passwort, über die Implementierung aus Spring Security. Es wird beim Login geprüft und nie entschlüsselt.
- AES-256-GCM für Tresoreinträge. Jeder Wert bekommt einen zufälligen 12-Byte-IV, und das GCM-Tag erkennt Manipulation.
- PBKDF2-HMAC-SHA256 mit 120.000 Iterationen leitet den Tresorschlüssel beim Login aus dem Passwort ab. Der Schlüssel existiert nur im Speicher.
- Versionierter Chiffretext. Verschlüsselte Werte beginnen mit
v1:, ältere Klartextzeilen werden also beim Laden erkannt und beim nächsten Speichern verschlüsselt. - MVC mit DAOs und HikariCP, und
CompletableFutureum die Authentifizierung, damit der JavaFX-Thread nie auf MySQL wartet. - Kleine Komfortfunktionen: Jsoup holt das Favicon jeder Website, Passwörter bleiben maskiert, bis man sie aufdeckt, und Zugangsdaten lassen sich kopieren, ohne angezeigt zu werden.
Ergebnis
Gespeicherte Passwörter in einem gestohlenen Datenbank-Dump sind ohne das Login-Passwort des Besitzers unlesbar. JUnit und Mockito decken Nutzerspeicherung und Authentifizierung ab. Eine Schwäche würde ich zuerst beheben: Der PBKDF2-Salt ist der Benutzername, und der ist vorhersagbar. Ein zufälliger Salt pro Nutzer, gespeichert neben dem BCrypt-Hash, würde das schließen.