Public-key cryptography
Understand public and private keys
Use a shareable public key and protected private key while keeping encryption, agreement, and signing purposes distinct.
Public-key cryptography splits key material into a public part and a private part. The two are mathematically linked: what one does, only the other can undo or verify. The private key never becomes public.
This solves the problem symmetric keys cannot: working with parties you have never shared a secret with. You publish the public key to anyone. You guard the private key like the secret it is.
import { generateKeyPairSync } from 'node:crypto'
const { publicKey, privateKey } = generateKeyPairSync('ed25519')
publicKey.export({ type: 'spki', format: 'pem' })
// -----BEGIN PUBLIC KEY----- <- share this freely
privateKey.export({ type: 'pkcs8', format: 'pem' })
// -----BEGIN PRIVATE KEY----- <- never leaves your control
One pair, one purpose
Depending on the construction, a key pair supports key agreement, encryption, or signatures. With signatures, the private key signs and anyone verifies with the public key. With encryption, anyone encrypts to the public key and only the private key decrypts. Some algorithms only do one job at all: Ed25519 keys sign, X25519 keys perform key agreement, and they are not interchangeable.
Do not assume one key pair should serve every purpose even when the math allows it. Keep signing, encryption, and key-agreement keys separate so compromise or misuse of one purpose does not cross into another. A leaked TLS key should never also be your release-signing key.
You will meet these pairs everywhere: your SSH key (~/.ssh/id_ed25519 and id_ed25519.pub), TLS server keys, package and commit signing keys.
Public does not mean trusted
Here is the trap. Public keys still need an authenticated way to bind them to the expected identity.
An application downloads a public key from the same unauthenticated response as the signed update. An attacker replaces the update, signature, and public key together. Every mathematical check passes, because the attacker signed their malware with their own key and handed you the matching verifier.
Public means shareable, not automatically trusted. The binding between a key and an identity has to come from somewhere the attacker does not control: a certificate chain, a key pinned at install time, or a fingerprint verified out of band. That binding problem is what the rest of this module is about.
Practice
Classify the public and private material for an SSH login, TLS site, and package-signing workflow, and save how each public key gains trust. Verify one signed test message with the expected public key. Then substitute a new attacker-controlled key pair and show why mathematical verification alone is insufficient.
Lesson completed