Skip to main content

Cryptography Basics

Networks move data across links you do not control - shared Wi-Fi, ISPs, routers owned by strangers. Cryptography is what lets two parties keep a conversation private and trustworthy over that hostile path. The first goal is confidentiality: turning readable data (plaintext) into scrambled data (ciphertext) that only the intended recipient can reverse.

There are two families of cryptography, and modern systems use both.

Symmetric-key cryptography

In symmetric cryptography, the same secret key both encrypts and decrypts. If Alice and Bob share a key, Alice encrypts with it and Bob decrypts with the same one. The workhorse algorithm is AES.

Symmetric encryption is fast - it can encrypt gigabytes per second in hardware - which is why it protects the bulk of the actual data. Its weakness is key distribution: Alice and Bob must somehow agree on a shared secret without an eavesdropper learning it. Over an open network, that is exactly the hard part.

Public-key cryptography

Public-key (asymmetric) cryptography gives each party a key pair: a public key anyone may know, and a private key kept secret. Data encrypted with the public key can only be decrypted with the matching private key. The common algorithms are RSA and ECC (elliptic-curve).

This solves key distribution: Bob can publish his public key openly, and anyone can encrypt a message only Bob can read. The catch is that public-key operations are much slower than symmetric ones, so we do not use them to encrypt bulk data.

Symmetric-keyPublic-key
KeysOne shared secret keyA key pair (public + private)
Same key both ways?YesNo - encrypt with one, decrypt with the other
SpeedFast (bulk data)Slow (small payloads only)
ExamplesAESRSA, ECC
Key distributionHard - must share the secret secretlyEasy - public key can be shared openly

How they combine

Real protocols get the best of both. Public-key cryptography solves the distribution problem, and symmetric cryptography does the fast bulk work, so they are used together:

  1. Use public-key cryptography to securely agree on a fresh symmetric session key.
  2. Use that fast symmetric key to encrypt the rest of the conversation.

This hybrid pattern is exactly what TLS (and therefore HTTPS) does on every connection.

Symmetric vs public-key, by the numbers

The two families are not just different in mechanism, they are different by orders of magnitude in both speed and the key sizes needed for equivalent strength:

  • Throughput - AES-128 with hardware acceleration (AES-NI) encrypts on the order of several GB/s per core. RSA-2048 private-key operations run at roughly 1,000-2,000 operations per second per core - a difference of five to six orders of magnitude.
  • Equivalent strength - to match the security of a 128-bit AES key, RSA needs roughly a 3072-bit key; matching a 256-bit AES key takes an RSA key around 15360 bits. Elliptic-curve keys stay much smaller: a 256-bit ECC key already matches AES-128.
  • Why this matters in practice - this is exactly why nobody RSA-encrypts a 10 MB file directly. Doing so at ~1,500 ops/sec would take far longer than users will wait, and RSA cannot even encrypt a payload larger than its key size. Instead RSA/ECC wraps a small (128- or 256-bit) AES session key in a few milliseconds, and AES does the rest of the work at line rate.
info

Public-key cryptography is elegant but slow; symmetric cryptography is fast but needs a pre-shared secret. Combining them - public-key to exchange a symmetric session key, symmetric to encrypt the data - gives you easy key distribution and high throughput. Neither family alone is enough.

Reusing a nonce breaks AES-GCM completely

Modern symmetric encryption (AES-GCM, ChaCha20-Poly1305) requires a unique nonce (a number used once) for every message encrypted under the same key. Reuse the same nonce and key pair for two different messages and an attacker who XORs the two ciphertexts recovers the XOR of the two plaintexts - and with GCM specifically, nonce reuse also leaks the authentication key, letting an attacker forge valid ciphertexts for any message afterward. This is not theoretical: it has caused real breaks in production systems that generated nonces from a counter that reset on restart, or from a weak/predictable random source instead of a proper CSPRNG. The fix is boring but non-negotiable: never hand-roll nonce generation, and never let a key be reused across enough messages that a 96-bit random nonce could plausibly collide.