Public-key crypto uses a key pair: share the public key, keep the private key secret. It solves key exchange and enables digital signatures — the basis of TLS, code signing, and JWTs.
Asymmetric (public-key) cryptography uses two mathematically linked keys. What one encrypts, only the other decrypts. You publish the public key freely and guard the private key. This asymmetry unlocks two capabilities symmetric crypto cannot: exchanging secrets with someone you have never met, and proving authorship with a signature.
Key pair: (public, private) — linked, but you can't derive private
from public.
Two modes, depending on which key does what:
ENCRYPT to someone: encrypt with THEIR public key
-> only THEIR private key can decrypt (confidentiality)
SIGN as yourself: sign with YOUR private key
-> anyone verifies with your public key (authenticity)
Slow vs symmetric, so in practice it's used to exchange a symmetric
key (then bulk-encrypt with that) — exactly what TLS does.Asymmetric crypto solves symmetric encryption's distribution problem. Using a key-agreement protocol (Diffie-Hellman / ECDH), two parties derive a shared secret over a public channel that an eavesdropper cannot reconstruct — even while watching every message. Modern TLS uses an ephemeral exchange so each session gets a fresh key, giving forward secrecy: stealing the long-term key later cannot decrypt past traffic.
Diffie-Hellman / ECDH — derive a shared secret over a public wire:
Alice + Bob each generate an ephemeral key pair, swap PUBLIC keys,
and each combines (their private + the other's public) to compute
the SAME shared secret. An eavesdropper sees both public keys but
cannot compute the secret.
Ephemeral (ECDHE) => FORWARD SECRECY: a new secret per session, so
compromising today's long-term key can't decrypt yesterday's traffic.
That shared secret becomes the AES key for the session (lesson 3).A signature is the reverse direction: you sign a message's hash with your private key, and anyone can verify it with your public key. A valid signature proves the message came from the holder of the private key and was not altered. This underpins TLS certificates, code signing (the Supply Chain course), JWT tokens, and software updates.
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.exceptions import InvalidSignature
priv = Ed25519PrivateKey.generate() # keep secret
pub = priv.public_key() # publish freely
msg = b"deploy build 1.5.0"
sig = priv.sign(msg) # sign with the PRIVATE key
# anyone with the public key verifies authenticity + integrity:
try:
pub.verify(sig, msg) # valid -> really from priv holder, unaltered
except InvalidSignature:
reject()
# Ed25519 = modern, fast, hard to misuse. This is what signs certs,
# code (cosign), and JWTs.Signatures verify a message came from a specific public key — but how do you know that public key really belongs to who you think? Anyone can generate a key pair and claim to be your bank. Binding a public key to a verified identity is exactly what certificates and PKI solve, which is the subject of the next two lessons.
Signatures prove: "this came from the holder of public key P, unaltered."
But they DON'T prove: "P belongs to bank.com and not an impostor."
attacker generates their own key pair, presents it as "bank.com",
signs their fake page perfectly -> your verify() passes -> you trust
the wrong key.
The missing piece: binding a public key to a VERIFIED IDENTITY.
That binding is a CERTIFICATE, issued by a trusted authority (a CA).
-> TLS & PKI, next.