# Encrypted Chat End-to-end encrypted chat s forward secrecy (X3DH + Double Ratchet, Signal Protocol). Server ukládá a přeposílá šifrované bloby — nikdy nevidí plaintext. ## Architektura ``` ┌─────────────┐ TLS/TCP ┌─────────────┐ MySQL ┌─────────┐ │ GUI/CLI │◄───────────────►│ Server │◄──────────────►│ DB │ │ klient │ JSON + base64 │ (asyncio) │ │ │ └─────────────┘ └─────────────┘ └─────────┘ │ │ │ X3DH + Double Ratchet │ Opaque blobs │ Sender Keys (skupiny) │ (server nevidí plaintext) ▼ ▼ Lokální klíče Šifrované zprávy (~/.encrypted_chat/) + metadata ``` ## Soubory ### Server | Soubor | Řádky | Účel | |--------|-------|------| | `server.py` | ~2 900 | Asyncio TCP server, 45 handlerů, rate limiting, 5 asyncio.Lock guardů, real-time notifikace | | `db.py` | ~1 700 | MySQL CRUD, connection pooling (pool_size=10), phantom users, reactions/pins CRUD | | `schema.sql` | ~190 | MySQL schéma (14 tabulek) | ### Klient | Soubor | Řádky | Účel | |--------|-------|------| | `gui_client.py` | ~6 300 | PyQt6 GUI — dark/light téma, widget-based message bubbles, verifikace kontaktů, privacy overlay | | `client.py` | ~900 | CLI klient — 23 menu opcí | | `chat_core.py` | ~3 500 | Sdílená logika — session management, X3DH/ratchet šifrování, lokální klíče, multi-device | | `theme.py` | ~540 | Catppuccin dark + Signal-inspired light téma, live switching | ### Sdílené (server + klient) | Soubor | Účel | |--------|------| | `crypto_utils.py` (~935 ř.) | Ed25519, X25519, AES-256-GCM, HKDF, PBKDF2, X3DH, Double Ratchet (state rollback), Sender Keys (state rollback), ECP1 key encryption, contact verification (fingerprints, safety numbers, QR), message padding | | `protocol.py` (~140 ř.) | Newline-delimited JSON protokol, base64 encoding, verze (0.8.4) | ### iOS klient | Složka | Účel | |--------|------| | `ios_client/` (47 Swift souborů, ~5 000 ř.) | Nativní iOS port — CryptoKit + pure Swift GF(2^255-19) + Security.framework RSA, SwiftUI views, wire-kompatibilní s Python serverem | ### Testy | Soubor | Účel | |--------|------| | `tests/pentest_client.py` (~340 ř.) | Automatizované security regresní testy (AuthZ, malformed headers, session reset, rate limits) | ## Quick Start 1. `pip install -r requirements.txt` 2. Spustit `schema.sql` v MySQL 3. `python server.py` 4. Klient: `python gui_client.py` (GUI) nebo `python client.py` (CLI) ## Jak funguje šifrování ### Klíče na uživatele | Klíč | Typ | Účel | |------|-----|------| | RSA-4096 | Asymetrický | Pouze login challenge-response. Šifrovaný ECP1 (PBKDF2 600k + AES-256-GCM). | | Identity Key (IK) | Ed25519 | Podpisy, konverze na X25519 pro X3DH. Šifrovaný ECP1. | | Signed Pre-Key (SPK) | X25519 | DH v X3DH, podepsaný IK. **Rotuje se každých 7 dní** s grace periodem. | | One-Time Pre-Keys (OPK) | X25519 | Jednorázové, spotřebuje se při X3DH, automaticky doplňované (< 20 → +50). | ### DM (1:1 zprávy) — X3DH + Double Ratchet 1. Alice stáhne Bobovy per-device key bundles (IK, SPK, OPK) → X3DH per device → shared secret per device. 2. Double Ratchet inicializován ze shared secret — jedna session per (user, device). 3. Každá zpráva: symmetric ratchet (HMAC chain) → message key → AES-256-GCM. 4. Každá odpověď: DH ratchet (nový X25519 keypair) → nový root key + chain key. 5. Per-device ciphertext — každé zařízení příjemce dostane individuálně šifrovaný blob. 6. Self-encrypted kopie s SELF_DEVICE_ID sentinel, čitelná všemi vlastními zařízeními. ### Skupiny — Sender Keys 1. Každý odesílatel má vlastní SenderKeyState per group. 2. Sender key distribuován členům přes pairwise Double Ratchet (jako control DM). 3. Skupinové zprávy: symmetric ratchet na sender key → AES-256-GCM. 4. Stejný ciphertext pro všechny příjemce (efektivní). ### Kontaktní verifikace (Signal-style) - **Safety numbers** — 60-digit číslo (12 skupin × 5 číslic), deterministické pro každý pár. - **QR kódy** — binární payload zakódovaný jako base64. - **Fingerprints** — 30-digit per-user číslo. - **TOFU** — Trust On First Use + explicit verification + key change warning. ### Lokální úložiště klíčů ``` ~/.encrypted_chat/{email}/ private.pem / public.pem — RSA (login, ECP1 formát) identity_private.bin / _public.bin — Ed25519 (ECP1 formát) device_id.txt — UUID tohoto zařízení spk_private.bin / spk_id.txt — Aktuální SPK (AES-256-GCM) prev_spk_private.bin / prev_spk_id.txt — Předchozí SPK, grace period opk_private/{opk_id}.bin — One-time prekeys (AES-256-GCM) sessions/{uid}_{did}.bin — Double Ratchet stavy (AES-256-GCM) sender_keys/{conv_id}.bin — Vlastní sender keys sender_keys_recv/{conv}_{uid}_{did}.bin — Přijaté sender keys known_identity_keys.bin — TOFU registr (AES-256-GCM) verified_contacts.bin — Explicitní verifikace (AES-256-GCM) message_cache/{conv_id}.bin — Šifrovaný message cache login_lockout.json — Brute-force lockout stav ``` ## Bezpečnostní hardening ### Šifrování privátních klíčů (ECP1 formát) - **PBKDF2-HMAC-SHA256** s 600 000 iteracemi (OWASP 2023) - **AES-256-GCM**, magic bytes "ECP1" jako AAD - **Formát:** `ECP1(4B) + salt(16B) + nonce(12B) + ciphertext+tag` - Zpětná kompatibilita: staré PEM se migrují automaticky ### Lokální šifrování dat - Session/sender key soubory, OPK, SPK, message cache, verifikační soubory — AES-256-GCM klíčem z HKDF(identity_key) - `chmod 0o700` na adresáře, `0o600` na soubory ### Brute-force ochrana - Exponenciální backoff: `min(2^N, 300)` sekund po N chybných pokusech - Aplikováno na login + privacy overlay unlock ### SPK rotace (7 dní) - Automatická rotace s grace periodem pro in-flight X3DH - Omezuje dopad kompromitace SPK ### Ratchet state rollback - Snapshot/restore při selhání dešifrování (DoubleRatchet + SenderKeyState) ### Secure deletion - Overwrite `os.urandom()` + `fsync` + `unlink` na smazané citlivé soubory ### Message padding - Bucketed padding (64B–64KB) maskuje délku zpráv ### Metadata privacy - Log sanitizace (žádná PII), metadata retention (90 dní), sender chain minimalizace ### Anti-enumeration - Phantom users pro neregistrované emaily - Generické odpovědi na register/login/get_user_info ## Multi-Device Support Pravý multi-device (Signal-like) — každé zařízení má nezávislé Double Ratchet sessions. - **Devices tabulka** — každé přihlášení registruje device (UUID) - **Per-device prekeys** — každé zařízení má vlastní SPK + OPKs - **Per-device sessions** — klíčované `"user_id:device_id"` - **Self-encryption** — statický klíč z identity key (čitelné všemi vlastními zařízeními) - **Pairing** — přenos RSA + Ed25519, nové zařízení generuje vlastní SPK + OPKs ## Features ### Protokol & šifrování - X3DH + Double Ratchet (DM) s forward secrecy - Sender Keys (skupiny) s distribucí přes pairwise ratchet - Per-device šifrování (multi-device) - SPK rotace (7 dní) + grace period - Ratchet state rollback při selhání - ECP1 šifrování klíčů (PBKDF2 600k) - Message padding (bucketed 64B–64KB) - Kontaktní verifikace (safety numbers, fingerprints, QR kódy) ### Komunikace - DM + skupinové konverzace - Reakce na zprávy (thumbsup, heart, laugh, surprised, sad, thumbsdown) - Přeposílání zpráv (text, obrázky, soubory) - Připnuté zprávy (pin/unpin + dialog) - @Mentions s autocomplete - Odpovědi na zprávy (reply_to) - Hledání zpráv (client-side, Ctrl+F) - Šifrované obrázky (AES-256-GCM, chunked upload, thumbnail) - Šifrované soubory (až 50 MB, chunked upload) - Read receipts (real-time) ### Skupiny - Skupinové pozvánky (accept/decline) - Leave group + přenos creatora - Rename group (creator only) - Delete conversation (DMs per-user, groups creator-only) - Group avatar ### Správa - Multi-device support (per-device sessions, pairing) - User profily (telefon, lokace, avatar, viditelnost) - Online/offline status - Session reset (při poškození ratchetu) - Key rotation (revokace zařízení) - Brute-force lockout ### GUI (PyQt6) - Dark (Catppuccin Mocha) + Light (Signal) téma s live switching - Widget-based message bubbles s ConversationDelegate - Cirkulární avatary + online zelená tečka - Unread count badges - Privacy overlay / lock screen (30s timeout + heslo) - Drag & drop souborů - Frameless dialogy - Connection indicator (green/red/orange) + auto-reconnect - VerificationDialog (safety numbers, QR, fingerprints) - Key change warning dialog ### CLI - 23 menu opcí (DM, skupiny, soubory, reakce, piny, forwarding, verifikace, zařízení, search) ### iOS (SwiftUI) - Wire-kompatibilní s Python serverem - Kompletní Signal Protocol (X3DH, Double Ratchet, Sender Keys) - CryptoKit + pure Swift field arithmetic + Security.framework RSA - SwiftUI views (login, chat, groups, profiles, search) ## Konfigurace ### Server + DB - `SERVER_HOST` (default `127.0.0.1`), `SERVER_PORT` (default `9999`) - `MYSQL_HOST`, `MYSQL_PORT`, `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_DATABASE` - `DB_POOL_SIZE` (default `10`) ### TLS - `TLS_ENABLED` — zapne TLS (default `false`) - `TLS_REQUIRED` — vyžaduje TLS_ENABLED - `TLS_CERT_FILE`, `TLS_KEY_FILE` — cesty k certifikátu (PEM) - `TLS_AUTOGEN` — auto-generuje self-signed cert (**jen s `ENVIRONMENT=dev`**) - `TLS_CA_FILE` (klient) — vlastní CA certifikát - `TLS_INSECURE` (klient) — vypne ověření certifikátu (**jen s `ENVIRONMENT=dev`**) ### SMTP - `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASS`, `SMTP_FROM` - Bez SMTP = dev mód (kód se vrací přímo klientovi) ### Limity - `MAX_MESSAGE_BYTES` (default `65536`), `MAX_IMAGE_BYTES` (5 MB), `MAX_FILE_BYTES` (50 MB) - `MAX_INPUT_CHARS` (GUI, default `2000`) - `METADATA_RETENTION_DAYS` (default `90`) - Rate limity: register 3/min, login 10/min, send_message 20/min - Connection: 20 req/s, max 10/IP, 200 global ### Logging - `LOG_LEVEL` (default `INFO`) ## Bezpečnostní audit Dva bezpečnostní audity provedeny (kód review). Nalezeno 6 CRITICAL, 12 HIGH, 12 MEDIUM, 8 LOW nálezů. | Závažnost | Celkem | Opraveno | Zbývá | |-----------|--------|----------|-------| | CRITICAL | 6 | **6** | 0 | | HIGH | 12 | **11** | 1 (H9 — by-design) | | MEDIUM | 12 | **11** | 1 (M7) | | LOW | 8 | **1** | 7 | Detaily viz `SECURITY_AUDIT.md` a `CLAUDE.md`. ## Known Issues - **Sender Key Redistribution:** Nový člen skupiny nedešifruje staré skupinové zprávy (sender keys se nedistribuují znovu při přidání). - **iOS: Contact Key Verification** — safety numbers, QR kódy, TOFU zatím neimplementovány v iOS klientu. ## Závislosti - `cryptography` — Ed25519, X25519, AES-GCM, RSA, HKDF, PBKDF2 - `mysql-connector-python` — MySQL s connection pooling - `python-dotenv` — env vars - `PyQt6` — GUI - `Pillow` — resize/thumbnail obrázků - `qrcode` — generování QR kódů - `pyzbar` (volitelné) — skenování QR kódů