BFEC (Bats' Fully Encrypted Chat)
This is a place to document my journey in building BFEC, a project aimed at learning how to implement a peer-to-peer chat. I chose Python for development because it allowed me to build the project quickly and focus on the core networking and encryption features.
To achieve this, I had to learn how to work with sockets and send data between peers.
Implementation
Connection Establishment
Establishing a connection between two peers involves following key steps:
- Connect to the server of the other peer. If the connection fails, become the server and allow the other peer to connect to the newly created server.
- Exchange RSA public keys and verify their integrity (by comparing checksum of both public keys).
- The peer hosting the server generates an AES key and shares it securely, using end-to-end encryption (E2E) with RSA (AES is used because RSA can't encrypt large amounts of data)
Metadata & Message
Each packet is divided into three segments:
- AES-Nonce (16 bytes): Required for AES decryption. This nonce is provided as header information and is not sensitive data.
- RSA-Signature (256 bytes): A checksum (sha256) of the unencrypted message, encrypted with the sender's RSA private key. The receiving peer can decrypt it with the sender’s public key and verify the checksum against the decrypted third segment (the encrypted message), protecting against man-in-the-middle (MITM) attacks.
- Encrypted Message (trailing bytes): The actual message, encrypted using AES, which can be decrypted using the AES nonce and the previously exchanged AES key.
Software Security
Current Security Risks
It’s important to note that this method cannot fully protect against a Man-In-The-Middle attack that intercepts the connection and replaces both public keys from the start. This is a issue that can not be solved when working with an unsecured/untrusted line of communication.
Implemented Security Measures
The critical phase of this implementation is during the connection and key exchange between peers. The primary threat is a MITM attack, where an attacker might replace the RSA public keys.
Two layers of protection are implemented:
Layer 1: Client-Side Public Key Verification
Both peers automatically verify a checksum of the combined public keys. Although this can still be compromised by a sophisticated MITM attack, it adds a first layer of defense.
This protects against a replaced public key during the key exchange of only one participant.
Layer 2: 2. RSA Signature Verification
The message checksum is encrypted with the sender’s RSA private key. The receiver can verify the integrity of the message using the sender's public key, ensuring the message hasn’t been tampered with, as long as the public key exchange was secure.
This protects against manipulated or altered messages after the initial key exchange.
Written: 2024-09-16