Files
Kecalek_python/README.md
Filip 2e7b72307d Initial commit — encrypted chat server + Python clients (v0.8.5)
E2E encrypted chat (X3DH + Double Ratchet, Signal Protocol).
Server: asyncio TCP + TLS, MySQL. Clients: PyQt6 GUI + CLI.
Secrets (.env, TLS keys, Cloudflare token), runtime data and
mobile clients (separate repos) are gitignored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 18:22:39 -04:00

327 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 (64B64KB) 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 64B64KB)
- 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.
## Docker a CI/CD
### Lokální vývoj s Docker Compose
```bash
# Spustit server + MySQL
docker compose up
# Rebuild po změně kódu
docker compose up --build
# Zastavit a smazat data
docker compose down -v
```
Server bude dostupný na `localhost:5000`. MySQL na `localhost:3306`.
Schéma se automaticky importuje při prvním spuštění.
### Ruční build Docker image
```bash
docker build -t encrypted-chat-server .
docker run -p 5000:5000 \
-e MYSQL_HOST=host.docker.internal \
-e MYSQL_USER=chat \
-e MYSQL_PASSWORD=chatpassword \
-e MYSQL_DATABASE=encrypted_chat \
-e ENVIRONMENT=dev \
encrypted-chat-server
```
### Produkční deployment
1. Získat TLS certifikát (Let's Encrypt / vlastní CA)
2. Nastavit env vars — viz `.env.example`
3. Spustit:
```bash
docker compose -f docker-compose.yml up -d
```
4. Ověřit health: `docker compose ps`
Kritické produkční proměnné:
- `TLS_ENABLED=true`, `TLS_CERT_FILE`, `TLS_KEY_FILE`
- `MYSQL_PASSWORD` — silné heslo
- `ENVIRONMENT=production` (ne `dev`)
- `SMTP_*` — pro registrační emaily
### CI/CD (GitHub Actions)
Pipeline v `.github/workflows/ci.yml` spouští při každém push/PR:
1. **Lint** — `ruff check` na všechny Python soubory
2. **Crypto testy** — `test_crypto_integration.py` (bez serveru)
3. **Integration testy** — spustí MySQL + server, pak `test_server_integration.py`
4. **Docker build** — ověří že se image builduje bez chyb
## 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ů