peer-to-peer encrypted chat that runs in your terminal. you host, you control. close the window β everything's gone.
every "secure" messenger still stores metadata somewhere. this doesn't. it's just two terminals talking over an encrypted tunnel. nothing written to disk, ever.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β SRP AUTHENTICATION β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β β β CLIENT SERVER β β β β β β βββββββββββββββ TCP CONNECT βββββββββββββββββββΊβ β β β β β β ββββ {"cmd":"srp_init","username","A"} βββββββΊ β β β β (A = client public ephemeral) β β β β β β β ββββββ {"user_id","B","salt","room_salt"} ββββ β β β β (B = server public ephemeral) β β β β β β β β [client derives room_key via HKDF: β β β β room_key = HKDF(password, room_salt)] β β β β β β β ββββ {"cmd":"srp_verify","user_id","M"} ββββββΊ β β β β (M = client proof) β β β β β β β ββββββββββ {"H_AMK","session_key"} βββββββββββ β β β β (H_AMK = server proof) β β β β β β β β [password never transmitted] β β β β [MITM can't derive session key] β β β β β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β E2E ENCRYPTED CHAT (same socket) β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β β β β β βββββββββ {"type":"init","messages","users"} β β β β β β β β βββ΄ββ ββββ΄βββ β β β C ββ {"type":"message","text":encrypted} ββΊβ S β β β β L β β E β β β β I ββββ {"type":"message","data":{...}} βββββ R β β β β E β β V β β β β N ββββ {"type":"user_joined",...} ββββββββββ E β β β β T β β R β β β β ββββ {"type":"user_left",...} ββββββββββββ β β β βββ¬ββ ββββ¬βββ β β β β β β β [server stores ONLY ciphertext] β β β β [server CANNOT read messages] β β β β [all clients with same password β β β β derive identical room_key] β β β β β β β β Encryption: Fernet (AES-128-CBC + HMAC) β β β β Key derivation: HKDF-SHA256 β β β β Protocol: newline-delimited JSON over TCP β β β β β β β β [on disconnect: keys wiped from RAM] β β β β β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β KEY HIERARCHY β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β β β password βββ¬βββΊ SRP βββΊ session_key (per-user, auth only) β β β β β ββββΊ HKDF(password, room_salt) βββΊ room_key (shared) β β β β room_salt: generated once at server start β β room_key: deterministic, same for all clients with same pwd β β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ SRP (Secure Remote Password) β password is never sent over the network. both sides prove they know it via zero-knowledge proof, then derive identical session keys.
git clone https://github.com/emilycodestar/cmd-chat.git cd cmd-chat python -m venv venv && source venv/bin/activate && pip install -r requirements.txtwindows:
python -m venv venv ; .\venv\Scripts\activate ; pip install -r requirements.txtstart server:
python cmd_chat.py serve 0.0.0.0 3000 --password mysecretconnect:
python cmd_chat.py connect SERVER_IP 3000 username mysecret- ram only β nothing touches disk
- pure sockets β no http, no websocket, just raw tcp
- srp auth β password never sent over network
- e2e encryption β Fernet (AES-128-CBC + HMAC)
- zero dependencies on web frameworks β only asyncio
MIT
