Skip to content

About

Encrypted client-server chat (ECDH, HKDF, AES-256-GCM, RSA-PSS) plus demos of ECB, padding-oracle and birthday attacks

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

crypto-secure-channel

A hands-on applied-cryptography project in two parts: an encrypted client-server chat (each client-server link has its own session key) built on modern primitives (ECDH key exchange, HKDF, AES-256-GCM, RSA-PSS signatures), and interactive demos of classic attacks on badly used cryptography (ECB pattern leakage, CBC padding oracle, birthday collisions). It shows both how to build a secure channel correctly and why common mistakes break.

Python cryptography License

Two parts:

  • Part A — a working encrypted chat (client-server) with ECDH key exchange, AES-256-GCM encryption, RSA signatures
  • Part B — three demos that show why bad crypto implementations get broken (ECB penguin, padding oracle, birthday attack)

Folder structure

secure_chat/
  crypto_utils.py    — all the crypto functions (ECDH, AES-GCM, RSA, HKDF)
  server.py          — multi-client chat server
  client.py          — terminal chat client

attack_demos/
  streamlit_app.py   — web UI for the demos
  demos/
    ecb_penguin.py
    padding_oracle.py
    birthday_attack.py

logs/                — handshake logs get dumped here

Setup

python -m venv venv
venv\Scripts\activate        # windows
# source venv/bin/activate   # linux/mac

pip install -r requirements.txt

Needs Python 3.9+.

Part A — Secure Chat

How the handshake works

When a client connects, this is what happens before any messages get sent:

CLIENT                                   SERVER
  |                                        |
  |  --- TCP connect ------------------>   |
  |  <-- server ECDH pub key (PEM) -----   |  server makes ephemeral ECDH keypair
  |  --- client ECDH pub key (PEM) ---->   |  client makes its own
  |                                        |
  |  both sides do ECDH -> shared secret   |
  |  run HKDF-SHA256 -> 256-bit AES key   |
  |                                        |
  |  <-- server RSA pub key (PEM) ------   |  for message signing
  |  --- client RSA pub key (PEM) ----->   |
  |  --- nickname --------------------->   |
  |                                        |
  |  === encrypted channel ready ========  |
  |  <-> AES-256-GCM + RSA-PSS sigs <->   |

Why I picked these primitives

  • ECDH (SECP384R1) for key exchange — gives forward secrecy, so even if keys leak later the old messages are safe. SECP384R1 is ~192-bit security level
  • HKDF-SHA256 for key derivation — raw ECDH output isn't uniformly random, HKDF fixes that
  • AES-256-GCM for encryption — authenticated encryption, handles confidentiality + integrity together. If someone modifies the ciphertext it just fails to decrypt
  • RSA-2048 with PSS padding for signatures — PSS is the modern padding scheme, better security guarantees than the older PKCS#1 v1.5

Running it

Start the server:

python -m secure_chat.server

Then connect clients (in separate terminals):

python -m secure_chat.client --nick Alice
python -m secure_chat.client --nick Bob

Type messages and they show up on the other side. Type quit to disconnect. Logs go to logs/server.log and logs/client.log.

Wire format

Messages are sent as length-prefixed JSON over TCP:

[4 bytes length][JSON payload]

Encrypted message looks like:

{
  "type": "message",
  "nonce": "hex 96-bit GCM nonce",
  "ciphertext": "hex AES-GCM ciphertext + tag",
  "signature": "hex RSA-PSS signature over nonce||ciphertext"
}

Part B — Crypto Attack Demos

Streamlit dashboard

streamlit run attack_demos/streamlit_app.py

Opens at localhost:8501. Has three tabs for the three demos.

Or run them individually:

python -m attack_demos.demos.ecb_penguin
python -m attack_demos.demos.padding_oracle
python -m attack_demos.demos.birthday_attack

ECB Penguin

Encrypts an image in ECB vs CBC mode. ECB encrypts blocks independently so patterns in the image are still visible after encryption. CBC chains blocks together so the output looks like noise. This is why you never use ECB for anything with structure.

Padding Oracle

Sets up a vulnerable CBC server that leaks whether padding is valid. The attack script exploits this to recover plaintext byte by byte without the key. Also shows the secure version (AES-GCM) where this attack is impossible since there's no padding to begin with.

Based on the Vaudenay attack (2002). Same class of bug behind POODLE and Lucky13 in TLS.

Birthday Attack

Shows that finding hash collisions is way easier than brute force. For an n-bit hash you only need ~2^(n/2) attempts (birthday paradox). The demo truncates SHA-256 to small sizes and finds collisions in real time, then compares across different hash sizes to show the scaling.


Tech stack

  • Python 3.9+
  • cryptography (ECDH SECP384R1, HKDF-SHA256, AES-256-GCM, RSA-2048 PSS, AES-ECB/CBC for the demos)
  • Python sockets + threading for the multi-client chat server
  • Streamlit for the attack-demo dashboard
  • Pillow for the ECB image demo

Known limitations

This is a learning project, not production software. Things I'd need to add for real use:

  • Not end-to-end: the server decrypts and re-encrypts each message, so it can read everything that is relayed
  • No certificate authority — the chat just trusts whatever RSA key it gets during handshake (vulnerable to MITM)
  • No key rotation — same session key for the whole connection
  • No cross-session replay protection
  • Forward secrecy depends on ephemeral keys actually being deleted from memory

These are documented on purpose — knowing what your system doesn't protect against matters just as much.

Future work: certificate-based or pinned-key authentication of the RSA keys (to stop MITM), periodic key rotation, message counters for replay protection, and automated tests for the protocol.

Ethical use

The attack demos run only against the toy servers included in this repo, to show why these implementation mistakes are dangerous. Don't use these techniques against systems you don't own or aren't authorized to test.

License

MIT

References

  • Vaudenay, S. (2002). Security Flaws Induced by CBC Padding
  • NIST SP 800-38D — GCM mode recommendation
  • NIST SP 800-56C — HKDF key derivation
  • Rizzo & Duong (2010). Practical Padding Oracle Attacks

About

Encrypted client-server chat (ECDH, HKDF, AES-256-GCM, RSA-PSS) plus demos of ECB, padding-oracle and birthday attacks

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages