asymmetric · level 3

Public vs Private

Encrypt with public, decrypt with private. Sign with private, verify with public.

120 XP

Public vs Private

Asymmetric cryptography uses two keys. They look the same — both are big random numbers — but they have different roles, and using the wrong one is the most common mistake people new to crypto make. This lesson is the mental model that prevents that mistake.

The two operations

Every keypair supports up to two operations, depending on the algorithm:

Direction Sender uses Receiver uses Property
Encrypt Receiver's public key Receiver's private key Confidentiality
Sign Sender's private key Sender's public key Authenticity

Notice the inversion. For encryption, the public key locks. For signatures, the private key locks. Same keypair, opposite roles — and the inversion catches a lot of people out the first time they read a crypto API.

The padlock metaphor

This is the metaphor that finally makes it click for most learners.

A public key is like an open padlock. You can hand them out to anyone — print them on the side of your van, paste them into your email signature. Anyone who wants to send you something secret can grab one of your padlocks, clamp it shut around their package, and put the package in the post. Only you have the key that opens it.

That covers encryption: the public-key-as-padlock locks the box; the private-key-as-key opens it.

For signatures, flip the metaphor:

A signature is like a tamper-evident wax seal embossed with your private signet ring. You — and only you — have the ring. Anyone with a photo of your seal pattern (the public key) can look at a sealed letter and confirm "yes, this matches the signet I expect from you, and the wax isn't broken, so it really came from you and hasn't been tampered with."

The private key signs (only you can stamp). The public key verifies (anyone can check).

Why does this work mathematically?

For RSA, a key has structure:

  • Public: (n, e) where n = p × q and e is conventionally 65537.
  • Private: (n, d) where d = e⁻¹ mod φ(n).

The encryption operation is c = m^e mod n. The decryption operation is m = c^d mod n. Because e × d ≡ 1 (mod φ(n)), the two exponents undo each other.

For a signature, you swap them: s = m^d mod n (only the private-key owner can do this), and verification is m' = s^e mod n (anyone with the public key can do this) followed by checking m' == hash(message).

For Ed25519, the operations don't work like that. Ed25519 only signs and verifies; it does not encrypt. If you want confidentiality, you use X25519 (a key-exchange primitive) to derive a shared secret and then symmetric-encrypt with that. Ed25519 + X25519 is the modern pattern that replaces "RSA does both" — see the diffie-hellman lesson.

Where the wrong key goes wrong

A few real-world failure modes:

  • "I encrypted my password with my own private key." No. You can't do that for confidentiality — anyone with your public key (which is, by definition, public) can decrypt it. You wanted symmetric encryption, or you wanted to send to their public key.
  • "I signed with the public key." Doesn't work — the public key can't sign, only verify. APIs that take the wrong key type usually error loudly, but if you're working with raw OpenSSL you can produce nonsense.
  • "I exchanged keys by emailing my private key over." Catastrophic. The private key never leaves the machine that generated it. You email public keys.

The visual model

Encryption (confidentiality):
                    ┌────────┐
   plaintext ──────▶│ ENCRYPT│ ◀── recipient's PUBLIC key
                    └────┬───┘
                         ▼
                    ciphertext
                         │
                    ┌────▼───┐
   plaintext ◀─────│ DECRYPT│ ◀── recipient's PRIVATE key
                    └────────┘

Signature (authenticity):
                    ┌────────┐
        message ───▶│  SIGN  │ ◀── sender's PRIVATE key
                    └────┬───┘
                         ▼
                    signature
                         │
                    ┌────▼───┐
   yes / no ◀──────│ VERIFY │ ◀── sender's PUBLIC key + message
                    └────────┘

Drawing this at a whiteboard before writing crypto code is consistently the highest-ROI minute you can spend.

Combining the two

In real protocols you almost always use both directions together. TLS does:

  1. Key exchange (asymmetric, using server's public key or X25519 ECDHE) — establishes a shared secret.
  2. Signature (asymmetric, using server's private key) — proves to the client that the server really is who its certificate claims.
  3. Symmetric encryption (using the shared secret from step 1) — encrypts the actual application data.

Asymmetric is for handshake; symmetric is for bulk data. The lesson on TLS goes deeper.

Summary

  • Public key locks (encryption); private key unlocks.
  • Private key signs; public key verifies.
  • Same keypair, opposite roles.
  • Public keys are public — handed out freely.
  • Private keys never leave the machine that made them.
  • RSA does both directions; Ed25519/ECDSA do signatures only and need X25519 for encryption.

Tools in the wild

4 tools
  • OpenSSLfree tier

    `openssl pkeyutl -encrypt` and `-sign` show the two directions explicitly.

    cli
  • agefree tier

    File encryption — recipient's public key locks, recipient's private key unlocks. Clean modern UX.

    cli
  • minisignfree tier

    Tiny signature tool. Sign with private, verify with public. Used by zig, dnscrypt, others.

    cli
  • GnuPGfree tier

    Both directions in one tool. `--encrypt` (uses public) and `--sign` (uses private).

    cli