E2EE-Chat is a local, zero-knowledge, end-to-end encrypted messaging application comprising a sleek desktop client GUI and a dedicated administrative relay server dashboard. Built natively using PySide6 (Qt) and hardened with modern asymmetric/symmetric primitives, the server serves exclusively as a blind packet dispatcher.
The server architecture cannot access, log, or read any unencrypted conversation payloads, cryptographic keys, or identity fingerprints.
- State-of-the-Art E2EE: Combines X25519 Ephemeral Key Exchanges and AES-256-GCM authenticated symmetric encryption executed locally in browser/client memory.
- Native Desktop Dashboards: High-fidelity dark-mode user interfaces for both the Client application and the Server Management Console.
- Enterprise Tunneling Out-of-the-Box: Auto-detects remote domain endpoints and seamlessly spins up local isolated reverse Cloudflare TCP Access Tunnels (
cloudflared). - Live Server Analytics: Graphical server console to monitor registered socket connections, tracking nodes, and localized system logs without compromising message content privacy.
- Passive Notifications: Full Windows/Linux system tray integration with message truncation previews and native system alerts.
The underlying core protocol relies on a tight coordination loop between the clients and the server instance:
[ Client A (Alice) ] [ Relay Server ] [ Client B (Bob) ]
| | |
|------ 1. Register Name ------>| |
| |<------ 2. Register Name ------|
| | |
|========== 3. X25519 Ephemeral Key Handshake ==========| |
|---- message-key-1 (PubA) ---->|------------------------------>|
|<--- message-key-1 (PubB) -----|<------------------------------|
|---- shared-key-ready -------->|------------------------------>|
|<--- shared-key-ready ---------|<------------------------------|
| | |
|==== 4. Derive Shared Session Key via HKDF-SHA256 ====| |
| | |
|== 5. Encrypt with AES-GCM and Send Blind Ciphertext ==| |
|--- [Nonce + Ciphertext] ----->|------------------------------>|
When a client initializes, it opens a raw TCP socket connection to the relay server. It sends an unencrypted register packet containing the chosen username. The server keeps a memory-bound registry mapping names to active network sockets.
Before any text messages can travel, the client demands the target peer's identity and initializes a secure key handshake:
- Alice's client generates a random, cryptographically secure X25519 Private Key and computes its corresponding Public Key.
- Alice packages her public key inside a
message-key-1packet targeted for Bob. The server receives this and passes it to Bob blindly. - Bob responds with his own
message-key-1containing his public key. - Both parties issue a
shared-key-readycommand confirmation to verify completion.
Both clients extract the peer's public key material and perform a Diffie-Hellman exchange against their own private parameters to output a shared master secret. This master secret is passed through a Hash-based Key Derivation Function (HKDF) using SHA-256 to create a static, unique 32-byte Symmetric Chat Key.
When Alice types a message and hits send:
- The client generates a random 12-byte initialization vector (Nonce).
- The raw string is encrypted using AES-GCM (Galois/Counter Mode) with the derived session key, producing ciphertext and an authentication tag.
- The client binds the
Nonce + Ciphertextinto anencrypted-chatstructural payload. - The server processes the envelope header, sees the destination username, and passes the payload along. It can never decode the message body since it lacks the private keys.
The implementation rejects legacy, insecure cryptography and opts strictly for modern performance:
| Component | Primitive | Details |
|---|---|---|
| Key Exchange | X25519 |
High-speed ECDH key agreement over Curve25519 |
| Key Derivation | HKDF-SHA256 |
Derives 32-byte keys using unique context tags |
| Symmetric Cipher | AES-256-GCM |
Authenticated encryption preventing chosen-ciphertext attacks |
| Entropy Engine | os.urandom() |
OS-level cryptographically secure random generation |
Network data frames traveling through sockets use explicit, predictable binary packing sizes structural headers via the Python struct format specifier !.
+----------------------------------+--------------------------+
| Command (32 Bytes Char) | Payload Length (UInt32) |
+----------------------------------+--------------------------+
+----------------------------+----------------------------+--------------------------+
| Command (32 Bytes Char) | Recipient (64 Bytes Char) | Payload Length (UInt32) |
+----------------------------+----------------------------+--------------------------+
- Python 3.10 or higher installed on your pathing layout.
- Optional:
cloudflaredinstalled system-wide if attempting to map local environments across active web domains.
git clone [https://github.com/CBHELEC/e2ee-chat.git](https://github.com/CBHELEC/e2ee-chat.git)
cd e2ee-chatpip install PySide6 cryptographyLaunch the central communication controller node first:
python server_gui.pyInput your preferred local host interface (e.g., 127.0.0.1 or 0.0.0.0 for all interfaces) along with the default target Port (724), and click Start Server.
Open two individual shell client terminal frameworks to simulate user interactions:
python client_gui.pyEnsure your Server targeting fields match the running instance.
Enter your distinct handle inside Username.
Target your peer's handle inside Chat With.
Hit Connect to run the handshake automatically and begin chatting securely!
Fork the Project
Create your Feature Branch (git checkout -b feature/AmazingFeature)
Commit your Changes (git commit -m 'Add some AmazingFeature')
Push to the Branch (git push origin feature/AmazingFeature)
Open a Pull Request