The problem
Send data from a client to a server through an attacker who can read, delete, and replay every packet, and still guarantee confidentiality, integrity, and that each side is talking to the other.
Key decisions
- Long-term keys only vouch for new ones
- The long-term RSA keys are used only to sign fresh session keys, which in turn sign an elliptic-curve Diffie-Hellman exchange. The attacker in the middle sees every key but can't forge one.
- A new key for every message
- Every message carries a new Diffie-Hellman public key, and the shared secret goes through a key-derivation function to become that message's AES key. Like the ratchet in Off-the-Record messaging, leaking one key exposes only one message.
- Separate keys for separate jobs
- Messages are encrypted with AES and signed with a different key, so breaking one doesn't give away the other.
- Counters against replay
- Every message carries a signed counter, so replayed, dropped, or reordered packets are detected and reported.
Results
- Detects tampered, replayed, reordered, and dropped messages
- Encryption and signing use separate keys
Built with
Python, PyCryptodome, AES, RSA, Elliptic-curve DH