This project implements a secure, multi-user communication system in Python. It demonstrates core concepts of public-key (asymmetric) cryptography to ensure message confidentiality, leveraging the cryptography
library. The system is designed around a logical grouping of users, where each user can manage multiple key pairs for sending and receiving encrypted messages.
- User and Group Management: Logically divides users into groups (e.g., 'Engineering', 'Marketing') to simulate a real-world organizational structure.
- Multiple Key Pairs per User: Each user can generate and manage multiple RSA public/private key pairs, allowing for flexible key rotation and management.
- Secure Private Key Storage: A user's private keys are never stored in plaintext. They are symmetrically encrypted using a master key derived from the user's password via PBKDF2, providing a strong layer of security against offline attacks.
- Public Key Distribution: Users maintain a table of their public keys, which can be shared with others to receive encrypted messages.
- ID-Based Encryption/Decryption: When sending a message, the ciphertext is accompanied by the specific
key_id
of the recipient's public key that was used. The recipient uses this ID to look up and decrypt the corresponding private key for successful message decryption. - Robust Cryptographic Primitives:
- Asymmetric Encryption: Uses RSA-2048 with OAEP padding for secure message encryption.
- Symmetric Encryption: Uses Fernet (AES-128-CBC) to encrypt and secure the private key files.
- Key Derivation: Implements PBKDF2HMAC with SHA-256 and a high iteration count (480,000) to derive strong encryption keys from user passwords, mitigating brute-force attacks.
- User Initialization: A user is created with a
name
and amaster_password
. A strong master key is derived from this password using a salt. - Key Generation: A user can generate any number of RSA key pairs.
- The public key is stored in a simple dictionary (
public_key_table
). - The private key is first encrypted using the user's master key and then stored in a separate dictionary (
private_key_store
).
- The public key is stored in a simple dictionary (
- Sending a Message:
- The sender (e.g., Alice) requests the public key of the recipient (e.g., Bob), specifying which key ID she wants to use (e.g.,
key_0
). - Alice uses Bob's public key to encrypt the message.
- She sends the resulting ciphertext along with the public key ID (
key_0
) to Bob.
- The sender (e.g., Alice) requests the public key of the recipient (e.g., Bob), specifying which key ID she wants to use (e.g.,
- Receiving a Message:
- Bob receives the ciphertext and the key ID.
- He uses the key ID to find the corresponding encrypted private key in his
private_key_store
. - He decrypts this private key using his master key (derived from his password).
- Finally, he uses the now-decrypted private key to decrypt the ciphertext and read the original message.
This system effectively demonstrates how an attacker (e.g., Charlie) who intercepts a message cannot decrypt it, as it was not encrypted with any of their public keys.
- Python 3.7+
- The
cryptography
library
-
Clone the repository:
git clone [https://github.com/your-username/secure-comm-system.git](https://github.com/your-username/secure-comm-system.git) cd secure-comm-system
-
Install the required package:
pip install cryptography
Execute the main script to see a demonstration of successful and failed communication scenarios:
python3 secure_comm_system.py
You will see output detailing:
- User and key pair creation.
- A successful encrypted communication from Alice to Bob.
- A successful reply from Bob to Alice using a different key.
- A demonstration of a failed decryption attempt by an unauthorized third party (Charlie).