Public-Key Cryptography Explained, With a Toy RSA Example

Public-key cryptography uses a pair of mathematically linked keys: a public key you can give to anyone and a private key only you hold. Data encrypted with the public key can be decrypted only with the private key, and a signature made with the private key can be checked by anyone with the public key.

That solves a problem a single shared password can't: two parties who have never met can communicate securely, and anyone can verify that a piece of software or a website really came from who it claims, without a secret ever being exchanged in advance.

Two keys, two jobs

GoalSender usesReceiver usesWhat it proves
Encryption (confidentiality)Recipient's public keyRecipient's private keyOnly the private-key holder can read it
Signature (authenticity)Signer's private keySigner's public keyThe private-key holder made it, and it hasn't changed

A common analogy for encryption is a padlock: you hand out open padlocks (public keys) freely, anyone can snap one shut on a box, but only you have the key that opens them. A signature is the reverse: only you can make it, everyone can check it.

A toy RSA example you can check by hand

This is a toy. The numbers are deliberately tiny so the arithmetic fits on paper, and anyone could break these keys instantly. Real RSA follows the same formulas with numbers hundreds of digits long, plus padding schemes that this example leaves out. The formulas are the RSA primitives from RFC 8017.

1. Make a key pair

  1. Pick two primes: p = 61, q = 53.
  2. Multiply them: n = 61 × 53 = 3233. This is the modulus, and it is part of both keys.
  3. Compute φ(n) = (p − 1)(q − 1) = 60 × 52 = 3120.
  4. Pick a public exponent e = 17. It must share no factors with 3120; 17 is prime and doesn't divide 3120, so it qualifies.
  5. Find the private exponent d such that e × d leaves remainder 1 when divided by 3120: d = 2753. Check: 17 × 2753 = 46801 = 15 × 3120 + 1.

Public key: (n = 3233, e = 17). Private key: (n = 3233, d = 2753).

A detail for careful readers: RFC 8017 states the condition using λ(n) = lcm(p − 1, q − 1) = lcm(60, 52) = 780 instead of φ(n). That gives a smaller valid exponent, d = 413 (17 × 413 = 7021 = 9 × 780 + 1), which decrypts the example below to the same result. Both are correct; the toy uses 2753 because the φ(n) version is the one most textbooks show.

2. Encrypt

RFC 8017 defines encryption as c = m^e mod n. Encrypt the message m = 65 with the public key:

c = 65^17 mod 3233

6517 is a 31-digit number, so compute it by repeated squaring, reducing mod 3233 at every step:

65^2  = 4225     → 4225 − 1 × 3233        = 992
65^4  = 992^2    = 984064  → − 304 × 3233 = 1232
65^8  = 1232^2   = 1517824 → − 469 × 3233 = 1547
65^16 = 1547^2   = 2393209 → − 740 × 3233 = 789
65^17 = 789 × 65 = 51285   → − 15 × 3233  = 2790

Ciphertext: c = 2790. Anyone could have done this, because it uses only the public key.

3. Decrypt

Decryption is m = c^d mod n:

m = 2790^2753 mod 3233 = 65

The original message comes back. The exponent is too large to show every squaring step, but the same method works: 2753 in binary is 101011000001, so it takes 11 squarings and a few multiplications, each reduced mod 3233. Without d you would have to find it from n and e, which means factoring 3233 back into 61 × 53.

4. Sign and verify

Signing swaps the roles of the exponents. RFC 8017 defines signing as s = m^d mod n and verification as m = s^e mod n. To sign the value 123:

s = 123^2753 mod 3233 = 2746        (needs the private key)
    2746^17  mod 3233 = 123         (anyone can check with the public key)

Verification by repeated squaring, as before:

2746^2  mod 3233 = 1160
2746^4  mod 3233 = 672
2746^8  mod 3233 = 2197
2746^16 mod 3233 = 3173
2746^17 = 3173 × 2746 = 8713058 → mod 3233 = 123

The check returns 123, so the signature is valid. Change one digit of the signature and the check returns a different number. In real systems the signed value is a hash of the document rather than the document itself; you can see what a SHA-256 hash looks like with larely's hash generator.

All the numbers above were checked with a short Node.js script using BigInt modular exponentiation.

Why real keys are so large

The toy breaks because 3233 factors instantly. The security of RSA rests on factoring a large n being impractical. NIST SP 800-131A Rev. 2 says the length of the modulus "shall be 2048 bits or more" to meet the minimum security strength of 112 bits for US federal use. A 2048-bit number has 617 decimal digits (2048 × log102 ≈ 616.5).

RFC 8017 also warns that the bare formulas "are not intended to provide security apart from a scheme." Real RSA encryption uses OAEP padding and real signatures use PSS, which add randomness and structure so that, for example, the same message never encrypts to the same ciphertext twice.

Where you use it every day

  • HTTPS (TLS 1.3). The server sends a certificate containing its public key, then proves it holds the private key with CertificateVerify: "a signature over the entire handshake using the private key corresponding to the public key in the Certificate message" (RFC 8446). Session keys come from an ephemeral Diffie-Hellman exchange; RFC 8446 notes that "static RSA and Diffie-Hellman cipher suites have been removed."
  • SSH logins. With key authentication, your client signs data that includes the session identifier using your private key. RFC 4252 says the server "MUST check that the key is a valid authenticator for the user, and MUST check that the signature is valid." See generating an SSH key to set one up.
  • Signed software and updates. Operating systems and package managers check a publisher's signature before installing, so a tampered download fails verification. FIPS 186-5, NIST's Digital Signature Standard, specifies approved signature algorithms for this kind of use.
  • Passkeys and security keys. The WebAuthn standard behind them creates a key pair per site. The site stores the public key, the authenticator signs each login with the private key, and that private key "is expected to never be exposed to any other party, not even to the owner of the authenticator."

Encrypting files with a password, as larely's text encryption tool does with AES-256-GCM, is the other family: symmetric cryptography, where the same secret encrypts and decrypts. Public-key systems usually use symmetric ciphers for the bulk data and public-key methods only to set up or protect the key.

Why the private key must stay private

Whoever holds the private key can decrypt everything sent to its public key and sign anything in your name, and nobody can tell the difference. That is why private keys are kept in files readable only by their owner, protected with a passphrase, or locked inside hardware (a security key, a phone's secure chip, a server's hardware security module) that signs without ever revealing the key. NIST devotes a whole recommendation, SP 800-57, to managing keys over their lifetime: generating, storing, rotating and retiring them. If a private key leaks, the fix is to revoke the matching public key or certificate and generate a new pair; there is no way to make a leaked key safe again.

Frequently asked questions

Can you work out the private key from the public key?
For RSA, doing so requires factoring the modulus n into its two primes. With the toy numbers in this article that takes seconds; with a 2048-bit modulus, the minimum NIST accepts for federal use, no practical method is publicly known. That one-way difficulty is what makes publishing the public key safe.
Is HTTPS encrypted with my browser's public key?
No. In TLS 1.3 the browser and server agree on fresh session keys using ephemeral Diffie-Hellman key exchange, and the server proves its identity by signing the handshake with the private key that matches its certificate. The bulk data is then encrypted with fast symmetric ciphers using the session keys.
What is the difference between encryption and a digital signature?
Encryption uses the recipient's public key so that only the holder of the matching private key can read the message. A signature uses the signer's private key so that anyone with the public key can check who signed it and that it hasn't changed. Encryption provides confidentiality; a signature provides authenticity and integrity, not secrecy.
Why not use public-key encryption for everything?
It is much slower than symmetric encryption and RSA can only encrypt a message smaller than its modulus. Real systems use public-key methods to agree on or protect a short symmetric key, then encrypt the actual data with a symmetric cipher such as AES.

Sources