Skip to content

mthri/e2ee-chat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Secure P2P Messenger

This project is a command-line, peer-to-peer (P2P) messaging application that uses a central relay server to establish connections. It features end-to-end encryption (E2EE) to ensure that only the communicating users can read the messages.

The core of the security model relies on a hybrid encryption scheme:

  • Asymmetric Encryption (RSA): Used for securely exchanging symmetric keys and verifying user identities through digital signatures.
  • Symmetric Encryption (AES-256-GCM): Used for encrypting the actual messages between clients, providing confidentiality and integrity.

Features

  • End-to-End Encryption: Messages are encrypted on the sender's client and decrypted only on the receiver's client. The relay server cannot read message content.
  • Secure Registration: Clients register with the server using an encrypted and signed payload, preventing tampering and ensuring authenticity.
  • Secure Peer Connection: A secure key exchange protocol establishes a shared secret key between two clients for their conversation.
  • Command-Line Interface: A simple and intuitive CLI for connecting to peers and exchanging messages.
  • In-memory Relay Server: A lightweight Flask-based server facilitates user discovery and message relaying without persisting message data.

How It Works

The security protocol follows these main steps:

  1. Server Key Generation: The relay.py server starts by generating its own RSA-2048 key pair. It exposes its public key via a public endpoint.

  2. Client Registration:

    • A new client (client.py) generates its own RSA key pair.
    • It fetches the server's public key and its SHA256 hash.
    • To prove its intent to register with this specific server, the client signs the server's public key hash with its own private key.
    • The client creates a payload containing its chosen name and public key. This entire payload is also signed.
    • A temporary AES key is generated. The signed payload is encrypted with this AES key.
    • Finally, the AES key itself is encrypted using the server's public RSA key.
    • The server receives this package, decrypts the AES key using its private RSA key, decrypts the payload, verifies both signatures, and registers the user. It returns a session secret (UUID) for authenticated actions.
  3. Peer-to-Peer E2EE Handshake:

    • Client A wants to talk to Client B. Client A requests Client B's public key from the server.
    • Client A generates a new shared AES key, which will be used for their private conversation.
    • Client A encrypts this shared AES key with Client B's public RSA key. It also signs the key to prove its origin.
    • This encrypted/signed key is sent to Client B via the relay server.
    • Client B uses its private RSA key to decrypt the shared AES key and verifies the signature using Client A's public key.
    • Both clients now possess the same shared secret AES key.
  4. Encrypted Messaging:

    • All subsequent messages between Client A and Client B are encrypted and decrypted using the shared AES key with the AES-GCM algorithm.

Installation

Prerequisites

  • Python 3.8+
  • pip

Setup

  1. Clone the repository:

    git clone https://github.com/mthri/e2ee-chat
    cd e2ee-chat
  2. Create and activate a virtual environment:

    # For macOS/Linux
    python3 -m venv venv
    source venv/bin/activate
    
    # For Windows
    python -m venv venv
    .\venv\Scripts\activate
  3. Install the dependencies:

    pip install -r requirements.txt

How to Run

You will need to run the relay server first, and then run two or more clients in separate terminal windows.

1. Run the Relay Server

For development, you can run the Flask server directly:

python relay.py

For a more robust setup, run the server using Gunicorn:

gunicorn --workers 4 --bind 0.0.0.0:5000 relay:app

This command starts the server on port 5000 with 4 worker processes.

⚠️ Very Important Note: In its current implementation, this application is not designed to work with multiple workers. Because all user data, inboxes, and session keys are stored in-memory (RAM), each Gunicorn worker will maintain its own separate, isolated copy of this information.

Consequently, a user registered by worker 1 will be completely unknown to worker 2, leading to authentication and messaging failures.

To test this project, you must use a single worker:

gunicorn --workers 1 --bind 0.0.0.0:5000 relay:app

2. Run the Client Application

Open two new terminal windows (with the virtual environment activated in each).

Terminal 1 (Alice):

python client.py
  • Enter name: Alice
  • The client will register and print your public key hash (your ID). It will look something like this:
    Registration successful!
    Your ID: a1b2c3d4e5f6...
    Secret: ...
    

Terminal 2 (Bob):

python client.py
  • Enter name: Bob
  • Bob's client will also register and print his unique public key hash.
    Registration successful!
    Your ID: f0e9d8c7b6a5...
    Secret: ...
    

3. Establish a Connection and Chat

Now, let's make Alice and Bob talk.

In Bob's Terminal:

  1. Type /wait to listen for incoming connection requests.
    /wait
    Waiting for incoming connections...
    

In Alice's Terminal:

  1. Use the /connect command with Bob's ID (his public key hash).
    /connect f0e9d8c7b6a5...
    
    You will see a confirmation that you are connected to Bob.

Chatting: Once the connection is established, both users will see a confirmation. They can now type messages and press Enter to send them securely.

# Alice's terminal
Hello Bob!

# Bob's terminal
Alice(a1b2c3d4e5f6...): Hello Bob!
> Hey Alice, how are you?

Client Commands

  • /connect <user_hash>: Initiates a secure connection with another user.
  • /wait: Puts your client in a listening mode to accept a connection.
  • /disconnect: Ends the current secure session.
  • /help: Displays available commands.
  • /quit or /exit: Exits the application.

About

A secure command-line messenger with End-to-End Encryption (E2EE) built in Python

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages