Cryptex — the server carries your messages. It just can't read them.
Cryptex is an end-to-end (E2E) encrypted 1:1 messaging application built over WebSockets. Utilizing a hybrid cryptographic scheme combining RSA asymmetric key exchange and AES-GCM symmetric message encryption, it ensures that the central relay server never has access to plaintext messages, private keys, or raw session keys.
The application uses an industry-standard hybrid encryption pattern:
- RSA-3072 for Key Exchange: RSA is highly secure but too slow for encrypting large amounts of data. We use 3072-bit keys (providing a higher security margin than 2048-bit keys) to encrypt the ephemeral AES keys.
- AES-256-GCM for Message Payload:
- For every single message sent, the sender generates a fresh, cryptographically secure 256-bit AES session key.
- The message is encrypted using AES-GCM (Galois/Counter Mode). This provides both confidentiality and authenticity (tamper detection).
- A unique 12-byte initialization vector (nonce) is generated randomly per message. Nonces are never reused under the same key.
- The ephemeral AES key is then encrypted with the recipient's RSA public key.
[Sender Client] [Recipient Client]
│ │
1. Generate AES key │
2. Encrypt msg with AES-GCM │
3. Encrypt AES key with │
Recipient's Public Key │
│ │
│───────[ JSON Message Bundle (Base64 Fields) ]─────────────►
│ (Through Server) │
│ │
│ 1. RSA-Decrypt AES key
│ with Private Key
│ 2. AES-GCM Decrypt msg
▼ ▼
Messages are transmitted as base64-encoded JSON strings:
{
"type": "message",
"encrypted_aes_key": "<base64 RSA-encrypted AES key>",
"nonce": "<base64 12-byte AES-GCM nonce>",
"ciphertext": "<base64 AES-GCM ciphertext>",
"tag": "<base64 16-byte AES-GCM auth tag>"
}- Client-Side Generation: RSA key pairs are generated locally. The private key never leaves the client's device/process.
- Passphrase-Derived Encryption at Rest: When generating or storing keys, the client can choose to encrypt the private key. It is saved in PEM format using PKCS#8 serialization with
BestAvailableEncryption(passphrase-derived key-wrapping).
Important
Educational Demonstration Only This repository is built as an educational demonstration of E2E encryption principles and is not audited for production/critical security environments.
- Public Key Authentication (MITM): This version does not implement out-of-band public-key fingerprint verification ("safety numbers"). A compromised or malicious server could theoretically perform a Man-in-the-Middle (MITM) attack by replacing the public keys during the initial connect-time key exchange.
- Forward Secrecy: While session keys are generated per-message, true forward secrecy requires a protocol such as Double Ratchet / X3DH (Signal Protocol) to derive new keys from ephemeral DH handshakes. If a private RSA key is compromised, historic message payloads captured on the wire could be decrypted.
- Metadata Leakage: The server knows when connections are active and which IP addresses are communicating.
cryptex/
├── cryptex/
│ ├── __init__.py
│ ├── server.py # WebSocket relay server & client pairing
│ ├── client.py # CLI-based E2E chat client
│ ├── crypto/
│ │ ├── __init__.py
│ │ ├── rsa_utils.py # RSA generation, serialization & encryption
│ │ ├── aes_utils.py # AES-GCM encrypt/decrypt wrappers
│ │ └── keystore.py # Keystore for encrypted private keys on disk
│ └── protocol.py # Message serialization (JSON + Base64)
├── tests/
│ ├── test_crypto.py # Unit tests for cryptographic primitives
│ └── test_integration.py # Server-client key exchange and relay tests
├── requirements.txt # Project dependencies
├── LICENSE # MIT License
└── README.md # Documentation
- Python 3.12+ installed.
-
Clone the repository:
git clone https://github.com/H8rsh100/Cryptex.git cd Cryptex -
Create a virtual environment and activate it:
python -m venv venv # On Windows (PowerShell): .\venv\Scripts\Activate.ps1 # On Linux/macOS: source venv/bin/activate
-
Install the dependencies:
pip install -r requirements.txt
Start the WebSocket relay server on localhost:8765:
python -m cryptex.serverYou can configure the host and port using environment variables:
# Windows
$env:CRYPTEX_HOST="0.0.0.0"
$env:CRYPTEX_PORT="8765"
# Linux/macOS
CRYPTEX_HOST="0.0.0.0" CRYPTEX_PORT="8765" python -m cryptex.serverOpen a terminal and start the client:
python -m cryptex.client- Enter a username (e.g.,
alice). - Follow the prompt to encrypt the private key with a password.
- Keep the default server URL (
ws://localhost:8765).
Open another terminal and start the client:
python -m cryptex.client- Enter a different username (e.g.,
bob). - Follow the prompt to set up password encryption for the keys.
- Enter the same server URL.
Once Bob connects, both clients will exchange public keys and establish an encrypted session. You can now chat! Type /exit to quit.
A comprehensive test suite is provided to verify unit-level cryptography and end-to-end messaging logic.
To execute tests:
pytest- Key Fingerprint Verification: UI to check safety numbers out-of-band to prevent MITM attacks.
- Double Ratchet Protocol: Ephemeral Diffie-Hellman handshakes for true forward secrecy.
- Client-Side Message Database: Encrypted sqlite database for local chat history.
- File Transfer: E2E encrypted local-to-local file transfers.