Skip to content

A fully functional end-to-end encrypted (E2EE) chat application built with vanilla JavaScript and Python. **Zero external crypto libraries** - uses only the native Web Crypto API.

License

Notifications You must be signed in to change notification settings

LoadingMagic/e2ee-Chat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”’ SecureChat - End-to-End Encrypted Messaging

A fully functional end-to-end encrypted (E2EE) chat application built with vanilla JavaScript and Python. Zero external crypto librariesβ€”uses only the native Web Crypto API.

⚠️ Educational Project: This is a demonstration of E2EE concepts. While the cryptography is solid, a production system would need additional hardening.

License Python JavaScript Website Download APK

✨ Features

  • True End-to-End Encryption – Messages are encrypted in the browser. The server sees only ciphertext.
  • No Account Required – No email, phone, or password. Just a cryptographic identity.
  • Recovery Key System – A 64-character hex key for account backup and restore.
  • Group Chats – Encrypted group messaging with AES key sharing.
  • Real-time Messaging – WebSocket-based instant delivery.
  • Rate Limiting – Built-in protection against abuse (registration, messages, groups).
  • Key Verification – Safety numbers to verify contact identity with a visual verification banner.
  • Cross-Platform – Web app and Android APK (via Capacitor).
  • Self-Hostable – Run your own server with full control.

πŸ” How The Encryption Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        KEY GENERATION                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Recovery Key (64 hex) ──► PBKDF2 ──► RSA-2048 Key Pair        β”‚
β”‚                                        β”œβ”€β”€ Public Key (shared) β”‚
β”‚                                        └── Private Key (local) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     MESSAGE ENCRYPTION                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Generate random AES-256 key for this message.               β”‚
β”‚  2. Encrypt message with AES-256-GCM.                           β”‚
β”‚  3. Encrypt AES key with recipient's RSA public key.            β”‚
β”‚  4. Send: [Encrypted AES Key + IV + Encrypted Message].         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     MESSAGE DECRYPTION                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Decrypt AES key using own RSA private key.                  β”‚
β”‚  2. Decrypt message using AES key + IV.                         β”‚
β”‚  3. Display plaintext to user.                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Cryptographic Primitives

Purpose Algorithm Details
Key Exchange RSA-OAEP 2048-bit modulus, SHA-256.
Message Encryption AES-GCM 256-bit key, 96-bit IV.
Key Derivation PBKDF2 SHA-256, 100,000 iterations.
User ID SHA-256 First 128 bits of hash.

What The Server Sees

// Server storageβ€”completely opaque.
{
  "sender_id": "a1b2c3d4e5f6...",
  "recipient_id": "9z8y7x6w5v4...",
  "encrypted_content": "Base64(RSA(AES_Key) + IV + AES(message))",
  "created_at": "2024-01-15T10:30:00Z"
}
// Server CANNOT read message contentβ€”no private keys.

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         FRONTEND                                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  app.js          β”‚  crypto.js       β”‚  websocket.js      β”‚  β”‚
β”‚  β”‚  - UI Logic      β”‚  - Web Crypto    β”‚  - Real-time       β”‚  β”‚
β”‚  β”‚  - State Mgmt    β”‚  - RSA/AES       β”‚  - Reconnection    β”‚  β”‚
β”‚  β”‚  - API Calls     β”‚  - Key Storage   β”‚  - Event Handling  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚ HTTPS / WSS
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         BACKEND                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  FastAPI                                                  β”‚  β”‚
β”‚  β”‚  - REST API (messages, users, groups).                   β”‚  β”‚
β”‚  β”‚  - WebSocket server (real-time delivery).                β”‚  β”‚
β”‚  β”‚  - Rate limiting (registration, messages, groups).       β”‚  β”‚
β”‚  β”‚  - NO encryption/decryption (just stores blobs).         β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  MySQL Database                                           β”‚  β”‚
β”‚  β”‚  - Users (public keys only).                             β”‚  β”‚
β”‚  β”‚  - Messages (encrypted blobs).                           β”‚  β”‚
β”‚  β”‚  - Groups (encrypted group keys per member).             β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Quick Start

Prerequisites

  • Python 3.8+
  • MySQL 8.0+
  • Node.js 16+ (for APK build only)

1. Clone & Setup

git clone https://github.com/yourusername/securechat.git
cd securechat

# Create virtual environment.
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# Install dependencies.
pip install fastapi uvicorn mysql-connector-python websockets python-dotenv

2. Configure Database

CREATE DATABASE securechat;
CREATE USER 'securechat'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON securechat.* TO 'securechat'@'localhost';

3. Environment Variables

Create .env in the backend folder:

DB_HOST=localhost
DB_USER=securechat
DB_PASSWORD=your_password
DB_NAME=securechat

4. Run

cd backend
python main.py

Visit http://localhost:8000β€”that's it!

5. Enable SRI (Subresource Integrity)

After configuring your server host in frontend/js/app.js, run the SRI script to enable code signing:

.\generate-sri.ps1

This generates SHA-384 hashes for all JS/CSS files and adds integrity attributes to index.html. If anyone tampers with your files, the browser will refuse to load them.

Important: Re-run this script every time you modify JS or CSS files.

πŸ“± Building the Android APK

cd frontend

# Install Capacitor.
npm install @capacitor/core @capacitor/cli @capacitor/android

# Initialize (first time only).
npx cap init SecureChat com.securechat.app

# Copy web files to www/.
.\build.ps1  # Or: node build.js

# Add Android platform.
npx cap add android

# Sync and build.
npx cap sync android
npx cap open android  # Opens Android Studio.

Build the APK in Android Studio: Build β†’ Build Bundle(s) / APK(s) β†’ Build APK(s).

πŸ“ Project Structure

securechat/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ main.py              # FastAPI server + WebSocket + Rate Limiting.
β”‚   β”œβ”€β”€ schema.sql           # Database schema.
β”‚   └── .env                 # Configuration (not in repo).
β”‚
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ index.html           # Single page app.
β”‚   β”œβ”€β”€ css/
β”‚   β”‚   └── style.css        # Dark theme UI.
β”‚   β”œβ”€β”€ js/
β”‚   β”‚   β”œβ”€β”€ app.js           # Main application logic.
β”‚   β”‚   β”œβ”€β”€ crypto.js        # Web Crypto API wrapper.
β”‚   β”‚   └── websocket.js     # Real-time connection.
β”‚   └── package.json
β”‚
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ API.md               # API documentation.
β”‚   └── ENCRYPTION.md        # Encryption details.
β”‚
β”œβ”€β”€ generate-sri.ps1         # SRI hash generator script.
└── README.md

πŸ”’ Security Features

What This Project Does Well

βœ… Proper E2EE – Private keys never leave the device.
βœ… Standard Algorithms – RSA-OAEP, AES-GCM, PBKDF2.
βœ… No Crypto Libraries – Native Web Crypto API only.
βœ… Server-Side Ignorance – Server cannot read messages.
βœ… Rate Limiting – Protection against brute-force and spam.
βœ… Key Verification – Safety numbers with visual verification banner.
βœ… Code Signing (SRI) – Subresource Integrity verifies frontend files haven't been tampered with. Run generate-sri.ps1 to enable.

Production Improvements Needed

⚠️ Forward Secrecy – Implement Double Ratchet (like Signal).
⚠️ Audit Logging – Security event monitoring.

Threat Model

Threat Mitigation
Server compromise Server has no keys, only encrypted blobs.
Network interception TLS + E2EE double protection.
Database leak Messages remain encrypted.
APK decompilation Security is in keys, not code.
Device theft Keys in localStorage (use device encryption).
Brute-force attacks Rate limiting on registration, messages, and groups.

🀝 Contributing

Contributions welcome! Areas that need work:

  • Forward secrecy (Double Ratchet).
  • File/image sharing.
  • Message search (client-side).
  • Desktop app (Electron).
  • iOS build.
  • Automated tests.

πŸ“š Learning Resources

If you're learning about E2EE, check out:

πŸ“„ License

MIT License – See LICENSE for details.


Built for learning. Use responsibly. Stay secure. πŸ”

About

A fully functional end-to-end encrypted (E2EE) chat application built with vanilla JavaScript and Python. **Zero external crypto libraries** - uses only the native Web Crypto API.

Resources

License

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •