Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,236 changes: 1,236 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@ tokio = { version = "1.40.0", features = ["full"] }
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140"
futures-util = "0.3.31"
tracing = "0.1.41"
tracing-subscriber = "0.3.19"
dashmap = "6.1.0"
uuid = { version = "1.10", features = ["v4"] }
thiserror = "2.0.12"
chrono = "0.4"
tokio-rustls = { version = "0.26.0", default-features = false, features = ["tls12", "ring", "logging"] }
tokio-rustls = { version = "0.26.0", default-features = false, features = ["tls12", "ring"] }
rustls = { version = "0.23", default-features = false, features = ["ring", "tls12"] }
rustls-pemfile = "2.2.0"
clap = { version = "4.5", features = ["derive"] }
async-trait = "0.1"
toml = "0.8.19"

rusqlite = { version = "0.37.0", features = ["bundled"] }
aes-gcm = "0.10.3"
base64 = "0.22.1"
rand = "0.8.5"
x509-parser = "0.16"
chrono = "0.4.38"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
127 changes: 60 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

![GitHub License](https://img.shields.io/badge/license-MIT-blue.svg) ![Rust](https://img.shields.io/badge/Rust-1.75%2B-orange.svg) ![Python](https://img.shields.io/badge/Python-3.8%2B-blue.svg)

**CipherMQ** is a secure, high-performance message broker designed for encrypted message transmission between senders and receivers using a push-based architecture. It leverages **hybrid encryption** (RSA + AES-GCM) for message confidentiality and authenticity, combined with **Mutual TLS (mTLS)** for secure client-server communication. The system ensures **zero message loss** and **exactly-once delivery** through robust acknowledgment mechanisms, with messages temporarily held in memory and routed via exchanges and queues.
**CipherMQ** is a secure, high-performance message broker designed for encrypted message transmission between senders and receivers using a push-based architecture. It leverages **hybrid encryption** (x25519 + AES-GCM-256) for message confidentiality and authenticity, combined with **Mutual TLS (mTLS)** for secure client-server communication. The system ensures **zero message loss** and **exactly-once delivery** through robust acknowledgment mechanisms, with messages temporarily held in memory and routed via exchanges and queues. Public keys are securely stored in an SQLite database with AES-GCM encryption, and receivers register their public keys with the server for secure distribution to senders.

This version introduces **TLS support**, enhancing security for client-server connections.

You can see some benchmarks regarding CipherMQ at [benchmark_report](benchmarks/benchmark_report.md). Initial architecture of CipherMQ is as follows:

Initial architecture of CipherMQ is as follows:



Expand All @@ -23,6 +23,8 @@ You can see some benchmarks regarding CipherMQ at [benchmark_report](benchmarks/





## Table of Contents
1. [Features](#features)
2. [Prerequisites](#prerequisites)
Expand All @@ -39,16 +41,17 @@ You can see some benchmarks regarding CipherMQ at [benchmark_report](benchmarks/

## Features

- **Mutual TLS (mTLS)**: Secure client-server communication with two-way authentication using X.509 certificates.
- **Hybrid Encryption**: RSA encrypts session keys, and AES-GCM ensures message encryption and authentication.
- **Mutual TLS (mTLS)**: Ensures secure client-server communication with two-way authentication using ECDSA P-384 certificates.
- **Hybrid Encryption**: Utilizes x25519 for session key encryption and AES-GCM-256 for message encryption and authentication.
- **Public Key Registration**: Receivers register their public keys with the server using the `register_key` command, which are securely stored and retrievable by senders via the `get_key` command.
- **Zero Message Loss**: Sender retries until server acknowledgment (`ACK <message_id>`), and server retries delivery until receiver acknowledgment (`ack <message_id>`).
- **Exactly-Once Delivery**: Receiver deduplicates messages using `message_id` to prevent reprocessing.
- **Batch Processing**: Sender collects and sends messages in batches, ensuring all queued messages are delivered.
- **Asynchronous Processing**: Built with Tokio for concurrent, high-performance connection handling.
- **Push-Based Messaging**: Messages are delivered to connected consumers.
- **Thread-Safe Data Structures**: Uses `DashMap` for safe multi-threaded operations.
- **Flexible Routing**: Supports exchanges and queues with routing keys for efficient message delivery.
- **Clear Acknowledgment Logging**: Both sender and receiver log ACKs for visibility (e.g., `✅ [SENDER] Server ACK received` and `✅ [RECEIVER] Server confirmed ACK`).
- **Secure Key Storage**: Public keys are encrypted with AES-GCM and stored in an SQLite database.



Expand All @@ -57,7 +60,8 @@ You can see some benchmarks regarding CipherMQ at [benchmark_report](benchmarks/
To run CipherMQ with TLS, you need:
- [Rust](https://www.rust-lang.org/): Version 1.56 or higher (for the server).
- [Python](https://www.python.org/): Version 3.8 or higher (for Sender and Receiver).
- [Key Generation](https://slproweb.com/products/Win32OpenSSL.html): Use OpenSSL or the provided `RSA.py` script to generate keys.
- Certificates Generation: Use the provided `generate_certs.py` script to generate mTLS certificates.
- Key Generation: Use the provided `key_maker.py` script to generate x25519 key pairs.



Expand All @@ -74,22 +78,13 @@ cd CipherMQ
cargo build --release
```
### 3. Generate mTLS Certificates
Generate a CA certificate, server certificate, and client certificate for mTLS:
Run the provided `generate_certs.py` script to generate CA certificates, server certificate, and client certificate for mTLS:

> **Note**: Press Enter to skip each question
```bash
mkdir -p certs src/client/certs
cd certs
openssl genrsa -out ca.key 2048
openssl req -x509 -new -key ca.key -out ca.crt -days 3650
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365
rm server.csr client.csr ca.srl
cp ca.crt client.crt client.key ../src/client/certs/
cd root
pip install cryptography
generate_certs.py

```

This creates:
Expand All @@ -101,21 +96,17 @@ This creates:

> **Note**: Store `ca.key` securely and do not distribute it. It is only used for certificate generation.

### 4. Generate x25519 Keys




### 4. Generate RSA Keys
Run the provided `RSA.py` script to generate RSA key pairs for hybrid encryption:
Run the provided `key_maker.py` script to generate x25519 key pairs for hybrid encryption for the receiver:
```bash
cd src/client
pip install pycryptodome
python RSA.py
python key_maker.py
```
This creates:
- `receiver_private.pem`: Receiver's private key for decryption.
- `receiver_public.pem`: Public key for sender encryption.

This creates:
- `receiver/certs/receiver_private.key`: Receiver's private key for decryption.
- `receiver/certs/receiver_public.key`: Public key for sender encryption.



Expand All @@ -124,41 +115,40 @@ This creates:
### Server Configuration
Create a `config.toml` file in the `CipherMQ` root directory:
```toml
[server]
connection_type = "tls"
address = "127.0.0.1:5672"

[tls]
cert_path = "certs/server.crt"
key_path = "certs/server.key"
ca_cert_path = "certs/ca.crt"

[database]
dbname = "public_keys.db"

[encryption]
aes_key = "YOUR_BASE64_ENCODED_32_BYTE_AES_KEY"
```

### Client Configuration
Create a config.json file in the src/client directory for Sender and Receiver, ensuring the following values are set:
```json
{
"exchange_name": "ciphermq_exchange",
"queue_name": "ciphermq_queue",
"routing_key": "ciphermq_key",
"server_address": "127.0.0.1",
"server_port": 5672,
"tls": {
"certificate_path": "certs/ca.crt",
"client_cert_path": "certs/client.crt",
"client_key_path": "certs/client.key",
"protocol": "PROTOCOL_TLS_CLIENT",
"verify_mode": "CERT_REQUIRED",
"check_hostname": false
}
}
> **Note**: Replace `YOUR_BASE64_ENCODED_32_BYTE_AES_KEY` with a 32-byte key encoded in base64. Generate it using:
```bash
openssl rand -base64 32
```

### Client Configuration
`config.json` file in both `sender/` and `receiver/` directories:`

> **Note**: Ensure `exchange_name`, `queue_name`, and `routing_key` match across Sender, Receiver, and server for proper message routing.

> **Security Note**: Restrict access to `server.key`, `client.key`, and `receiver_private.pem` (e.g., `chmod 600`).
> **Security Note**: Restrict access to `server.key`, `client.key`, and `receiver_private.key (e.g., `chmod 600`).



## Usage

### 1. Run the Server
Start the server with mTLS support:
Start the server with TLS support:
```bash
cd root
cargo run --release
Expand All @@ -167,46 +157,49 @@ cargo run --release
### 2. Run the Receiver
Start the receiver to subscribe to messages:
```bash
cd src/client
cd src/client/receiver
python Receiver.py
```
The receiver connects to the server via TLS, declares and binds to `ciphermq_queue`, decrypts messages, and saves them to `received_messages.jsonl`.
The receiver connects to the server via TLS, registers its public key using the `register_key` command, declares and binds to `my_queue`, decrypts messages, and saves them to `data/received_messages.jsonl`.

### 3. Run the Sender
Send encrypted messages in batches:

```bash
cd src/client
cd src/client/sender
python Sender.py
```
The sender encrypts messages using hybrid encryption, sends them in batches via `ciphermq_exchange` and `ciphermq_key`, and retries until acknowledgment.

The sender fetches the receiver's public key using the `get_key` command, encrypts messages using hybrid encryption, sends them in batches via `my_exchange` and `my_key`, and retries until acknowledgment.


## Architecture

CipherMQ is a message broker system with the following components:
- **Server** (`main.rs`, `server.rs`, `connection.rs`, `state.rs`, `config.rs`, `auth.rs`): A Rust-based broker that handles mTLS connections, message routing, and delivery using exchanges and queues.
- **Sender** (`Sender.py`): Encrypts messages with hybrid encryption (RSA + AES-GCM), sends them in batches, and ensures delivery with retries.
- **Receiver** (`Receiver.py`): Receives, decrypts, deduplicates, and stores messages in JSONL format, with acknowledgment retries.
- **Server** (`main.rs`, `server.rs`, `connection.rs`, `state.rs`, `config.rs`, `auth.rs`, `storage.rs`): A Rust-based broker that handles mTLS connections, message routing, and delivery using exchanges and queues. Public keys are encrypted with AES-GCM and stored in an SQLite database. The server supports the `register_key` command to store receiver public keys and the `get_key` command to provide them to senders.
- **Sender** (`sender.py`): Fetches receiver public keys using `get_key`, encrypts messages with hybrid encryption (x25519 + AES-GCM-256), sends them in batches, and ensures delivery with retries.
- **Receiver** (`receiver.py`): Registers its public key with the server using `register_key`, receives, decrypts, deduplicates, and stores messages in JSONL format, with acknowledgment retries.
- **mTLS Integration** (`auth.rs`, `connection.rs`): Supports secure two-way authentication using `tokio-rustls` and `WebPkiClientVerifier`.
- **Hybrid Encryption**: Combines RSA for session key encryption and AES-GCM for message encryption and authentication.
- **Hybrid Encryption**: Combines x25519 for session key encryption and AES-GCM-256 for message encryption and authentication.
- **Key Storage** (`storage.rs`): Public keys are encrypted with AES-GCM and stored in an SQLite database, accessible via `register_key` and `get_key` commands.

For a detailed architecture overview, see [CipherMQ Project Architecture](docs/Project_Architecture.md).



## Diagrams
The following diagrams, located in `docs/diagrams`, illustrate CipherMQ's architecture and mTLS flow:
- **[Sequence Diagram](docs/diagrams/Sequence_diagram.png)**: Shows the end-to-end message flow, including mTLS handshakes.
- **[Activity Diagram](docs/diagrams/Activity_Diagram.png)**: Details the operational flow, including mTLS connection setup.
- **[Sequence Diagram](docs/diagrams/Sequence_diagram.png)**: Shows the end-to-end message flow, including mTLS handshakes, public key registration, and hybrid encryption.
- **[Activity Diagram](docs/diagrams/Activity_Diagram.png)**: Details the operational flow, including mTLS connection setup, key registration, and message processing.

## Future Improvements
- Support standard protocols like AMQP or MQTT.
- Enable distributed server scaling.
- Replacing OpenSSL commands with specialized Rust libraries for generating keys and certificates.
- For generating a key to migrate from 2048-bit RSA to ECDSA(P-384)
- Support standard protocols like AMQP or MQTT for broader compatibility.
- Enable distributed server scaling for high availability.
- Replacing Python Script with specialized Rust libraries for generating keys and certificates.
- Implement certificate rotation and CRL/OCSP for enhanced security.
- Add support for Hardware Security Modules (HSM) for key management.
- Add persistent message storage to handle server restarts.
- Enhance monitoring with structured logging (optional reintroduction).



## Contributing
Contributions are welcome! Please:
Expand Down
15 changes: 11 additions & 4 deletions config.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
connection_type = "tls"
[server]
address = "127.0.0.1:5672"
connection_type = "tls"


cert_path = "certs/server.crt"
key_path = "certs/server.key"
[tls]
cert_path = "certs/server.crt"
key_path = "certs/server.key"
ca_cert_path = "certs/ca.crt"

[database]
dbname = "public_keys.db"

[encryption]
algorithm = "x25519_chacha20_poly1305"
aes_key = "YOUR_BASE64_ENCODED_32_BYTE_AES_KEY"
Loading