Closes #96 ## App - E2EEKeyManager: Tink HPKE Schlüsselpaar generieren, privaten Key via EncryptedSharedPreferences sichern, Nachrichten verschlüsseln und entschlüsseln (X25519 + ChaCha20-Poly1305) - EnsureKeyPairUseCase: Keypair-Initialisierung beim App-Start; Public Key via HTTP PUT an Server übermitteln - MainActivity: EnsureKeyPairUseCase.execute() in onCreate - SettingsKey: E2EEPrivateKeyset + E2EEPublicKeyBase64 als SENSITIVE_KEYS - MessageRepositoryImpl: sendMessage verschlüsselt Body mit Empfänger- Public-Key; eingehende Nachrichten werden lokal entschlüsselt und als Klartext in Room gespeichert; Public-Key-Cache (in-memory) + key_updated Handler - WebSocketClient: KeyUpdated Event hinzugefügt - WebSocketClientImpl: key_updated Frame parsen; Exception-Logging - Tink 1.15.0 als neue Dependency ## Server - V4 Flyway Migration: ALTER TABLE users ADD COLUMN public_key TEXT - Tables.kt: publicKey Feld in Users-Objekt - UserRepository: getPublicKey() / setPublicKey() - UserRoutes: PUT /api/users/{id}/public-key (Auth + Owner-Check + Längenvalidierung ≤ 10.000 Zeichen) und GET /api/users/{id}/public-key - WebSocketManager: notifyKeyUpdated() Broadcast an alle anderen verbundenen Clients - MessageRepository: EncryptionService für message body bypassed – Server speichert E2EE-Ciphertext direkt (Zero-Knowledge) ## Tests - E2EEKeyManagerTest: 5 Tests (Roundtrip, Nonce-Uniqueness, Wrong-Key, hasKeyPair) - EnsureKeyPairUseCaseTest: 4 Tests (generate+upload, skip wenn vorhanden, kein Upload ohne UserId, kein Crash bei Server-Fehler) - MessageRepositoryImplTest: 5 neue E2EE-Tests ## Docs - docs/migration-guide.md: E2EE-Einschränkungen dokumentiert (Pending-Message Klartext in SQLite) ## Follow-up - #105: E2EE Private Key – AndroidKeysetManager statt CleartextKeysetHandle (Security Hardening) |
||
|---|---|---|
| .. | ||
| data | ||
| keys | ||
| src | ||
| build.gradle.kts | ||