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 β
β β β β
β ββββββββ POST /srp/init {username, A} ββββββββΊ β β
β β (A = client public ephemeral) β β
β β β β
β ββββββ {user_id, B, salt, room_salt} βββββββββ β β
β β (B = server public ephemeral) β β
β β (room_salt = E2E key derivation) β β
β β β β
β β [client derives room_key via HKDF: β β
β β room_key = HKDF(password, room_salt)] β β
β β β β
β β [both sides compute SRP session key β β
β β using password + ephemeral values] β β
β β β β
β ββββββββ POST /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 β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β β β
β ββββββββ WebSocket /ws/chat?user_id ββββββββββΊ β β
β β (authenticated session) β β
β β β β
β β β β
β βββ΄ββ ββββ΄βββ β
β β C βββββ encrypt(msg, room_key) ββββββββββββΊβ S β β
β β L β β E β β
β β I βββββ ciphertext (broadcast) βββββββββββββ R β β
β β E β β V β β
β β N β decrypt(ciphertext, room_key) β E β β
β β T β β R β β
β βββ¬ββ ββββ¬βββ β
β β β β
β β [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 β β
β β β β
β β [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
- rsa + aes β key exchange + symmetric encryption
- no central server β direct p2p connection
- srp auth β password never sent over network
MIT
