Skip to content

Commit d4bae96

Browse files
authored
Merge pull request #7 from fozouni/feature/key-exchange-sqlite
Feature/key exchange sqlite
2 parents eb9a82f + 8d718ae commit d4bae96

20 files changed

+2592
-191
lines changed

Cargo.lock

Lines changed: 1236 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@ tokio = { version = "1.40.0", features = ["full"] }
88
serde = { version = "1.0.219", features = ["derive"] }
99
serde_json = "1.0.140"
1010
futures-util = "0.3.31"
11-
tracing = "0.1.41"
12-
tracing-subscriber = "0.3.19"
1311
dashmap = "6.1.0"
1412
uuid = { version = "1.10", features = ["v4"] }
1513
thiserror = "2.0.12"
16-
chrono = "0.4"
17-
tokio-rustls = { version = "0.26.0", default-features = false, features = ["tls12", "ring", "logging"] }
14+
tokio-rustls = { version = "0.26.0", default-features = false, features = ["tls12", "ring"] }
1815
rustls = { version = "0.23", default-features = false, features = ["ring", "tls12"] }
1916
rustls-pemfile = "2.2.0"
20-
clap = { version = "4.5", features = ["derive"] }
2117
async-trait = "0.1"
2218
toml = "0.8.19"
23-
19+
rusqlite = { version = "0.37.0", features = ["bundled"] }
20+
aes-gcm = "0.10.3"
21+
base64 = "0.22.1"
22+
rand = "0.8.5"
23+
x509-parser = "0.16"
24+
chrono = "0.4.38"
25+
tracing = "0.1.40"
26+
tracing-subscriber = "0.3.18"

README.md

Lines changed: 60 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99

1010
![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)
1111

12-
**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.
12+
**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.
1313

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

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

1818

1919

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

2424

2525

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

4042
## Features
4143

42-
- **Mutual TLS (mTLS)**: Secure client-server communication with two-way authentication using X.509 certificates.
43-
- **Hybrid Encryption**: RSA encrypts session keys, and AES-GCM ensures message encryption and authentication.
44+
- **Mutual TLS (mTLS)**: Ensures secure client-server communication with two-way authentication using ECDSA P-384 certificates.
45+
- **Hybrid Encryption**: Utilizes x25519 for session key encryption and AES-GCM-256 for message encryption and authentication.
46+
- **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.
4447
- **Zero Message Loss**: Sender retries until server acknowledgment (`ACK <message_id>`), and server retries delivery until receiver acknowledgment (`ack <message_id>`).
4548
- **Exactly-Once Delivery**: Receiver deduplicates messages using `message_id` to prevent reprocessing.
4649
- **Batch Processing**: Sender collects and sends messages in batches, ensuring all queued messages are delivered.
4750
- **Asynchronous Processing**: Built with Tokio for concurrent, high-performance connection handling.
4851
- **Push-Based Messaging**: Messages are delivered to connected consumers.
4952
- **Thread-Safe Data Structures**: Uses `DashMap` for safe multi-threaded operations.
5053
- **Flexible Routing**: Supports exchanges and queues with routing keys for efficient message delivery.
51-
- **Clear Acknowledgment Logging**: Both sender and receiver log ACKs for visibility (e.g., `✅ [SENDER] Server ACK received` and `✅ [RECEIVER] Server confirmed ACK`).
54+
- **Secure Key Storage**: Public keys are encrypted with AES-GCM and stored in an SQLite database.
5255

5356

5457

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

6266

6367

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

79-
> **Note**: Press Enter to skip each question
8083
```bash
81-
mkdir -p certs src/client/certs
82-
cd certs
83-
openssl genrsa -out ca.key 2048
84-
openssl req -x509 -new -key ca.key -out ca.crt -days 3650
85-
openssl genrsa -out server.key 2048
86-
openssl req -new -key server.key -out server.csr
87-
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
88-
openssl genrsa -out client.key 2048
89-
openssl req -new -key client.key -out client.csr
90-
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365
91-
rm server.csr client.csr ca.srl
92-
cp ca.crt client.crt client.key ../src/client/certs/
84+
cd root
85+
pip install cryptography
86+
generate_certs.py
87+
9388
```
9489

9590
This creates:
@@ -101,21 +96,17 @@ This creates:
10196

10297
> **Note**: Store `ca.key` securely and do not distribute it. It is only used for certificate generation.
10398
99+
### 4. Generate x25519 Keys
104100

105-
106-
107-
108-
### 4. Generate RSA Keys
109-
Run the provided `RSA.py` script to generate RSA key pairs for hybrid encryption:
101+
Run the provided `key_maker.py` script to generate x25519 key pairs for hybrid encryption for the receiver:
110102
```bash
111103
cd src/client
112-
pip install pycryptodome
113-
python RSA.py
104+
python key_maker.py
114105
```
115-
This creates:
116-
- `receiver_private.pem`: Receiver's private key for decryption.
117-
- `receiver_public.pem`: Public key for sender encryption.
118106

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

120111

121112

@@ -124,41 +115,40 @@ This creates:
124115
### Server Configuration
125116
Create a `config.toml` file in the `CipherMQ` root directory:
126117
```toml
118+
[server]
127119
connection_type = "tls"
128120
address = "127.0.0.1:5672"
121+
122+
[tls]
129123
cert_path = "certs/server.crt"
130124
key_path = "certs/server.key"
131125
ca_cert_path = "certs/ca.crt"
126+
127+
[database]
128+
dbname = "public_keys.db"
129+
130+
[encryption]
131+
aes_key = "YOUR_BASE64_ENCODED_32_BYTE_AES_KEY"
132132
```
133133

134-
### Client Configuration
135-
Create a config.json file in the src/client directory for Sender and Receiver, ensuring the following values are set:
136-
```json
137-
{
138-
"exchange_name": "ciphermq_exchange",
139-
"queue_name": "ciphermq_queue",
140-
"routing_key": "ciphermq_key",
141-
"server_address": "127.0.0.1",
142-
"server_port": 5672,
143-
"tls": {
144-
"certificate_path": "certs/ca.crt",
145-
"client_cert_path": "certs/client.crt",
146-
"client_key_path": "certs/client.key",
147-
"protocol": "PROTOCOL_TLS_CLIENT",
148-
"verify_mode": "CERT_REQUIRED",
149-
"check_hostname": false
150-
}
151-
}
134+
> **Note**: Replace `YOUR_BASE64_ENCODED_32_BYTE_AES_KEY` with a 32-byte key encoded in base64. Generate it using:
135+
```bash
136+
openssl rand -base64 32
152137
```
153138

139+
### Client Configuration
140+
`config.json` file in both `sender/` and `receiver/` directories:`
141+
154142
> **Note**: Ensure `exchange_name`, `queue_name`, and `routing_key` match across Sender, Receiver, and server for proper message routing.
155143
156-
> **Security Note**: Restrict access to `server.key`, `client.key`, and `receiver_private.pem` (e.g., `chmod 600`).
144+
> **Security Note**: Restrict access to `server.key`, `client.key`, and `receiver_private.key (e.g., `chmod 600`).
145+
157146

158147

159148
## Usage
149+
160150
### 1. Run the Server
161-
Start the server with mTLS support:
151+
Start the server with TLS support:
162152
```bash
163153
cd root
164154
cargo run --release
@@ -167,46 +157,49 @@ cargo run --release
167157
### 2. Run the Receiver
168158
Start the receiver to subscribe to messages:
169159
```bash
170-
cd src/client
160+
cd src/client/receiver
171161
python Receiver.py
172162
```
173-
The receiver connects to the server via TLS, declares and binds to `ciphermq_queue`, decrypts messages, and saves them to `received_messages.jsonl`.
163+
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`.
174164

175165
### 3. Run the Sender
176-
Send encrypted messages in batches:
166+
177167
```bash
178-
cd src/client
168+
cd src/client/sender
179169
python Sender.py
180170
```
181-
The sender encrypts messages using hybrid encryption, sends them in batches via `ciphermq_exchange` and `ciphermq_key`, and retries until acknowledgment.
182-
171+
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.
183172

184173

185174
## Architecture
186175

187176
CipherMQ is a message broker system with the following components:
188-
- **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.
189-
- **Sender** (`Sender.py`): Encrypts messages with hybrid encryption (RSA + AES-GCM), sends them in batches, and ensures delivery with retries.
190-
- **Receiver** (`Receiver.py`): Receives, decrypts, deduplicates, and stores messages in JSONL format, with acknowledgment retries.
177+
- **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.
178+
- **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.
179+
- **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.
191180
- **mTLS Integration** (`auth.rs`, `connection.rs`): Supports secure two-way authentication using `tokio-rustls` and `WebPkiClientVerifier`.
192-
- **Hybrid Encryption**: Combines RSA for session key encryption and AES-GCM for message encryption and authentication.
181+
- **Hybrid Encryption**: Combines x25519 for session key encryption and AES-GCM-256 for message encryption and authentication.
182+
- **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.
193183

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

196186

197187

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

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

211204
## Contributing
212205
Contributions are welcome! Please:

config.toml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
connection_type = "tls"
1+
[server]
22
address = "127.0.0.1:5672"
3+
connection_type = "tls"
34

4-
5-
cert_path = "certs/server.crt"
6-
key_path = "certs/server.key"
5+
[tls]
6+
cert_path = "certs/server.crt"
7+
key_path = "certs/server.key"
78
ca_cert_path = "certs/ca.crt"
89

10+
[database]
11+
dbname = "public_keys.db"
12+
13+
[encryption]
14+
algorithm = "x25519_chacha20_poly1305"
15+
aes_key = "YOUR_BASE64_ENCODED_32_BYTE_AES_KEY"

0 commit comments

Comments
 (0)