Skip to main content
RunBook Academy

Secrets, PKI & CertificatesIII · Cryptography for Infrastructure EngineersCryptography

Key pairs, signing and key agreement: what a public key is actually for

Foundation⏱ ~22 minopensslssh-keygen

What you'll learn

  • Explain why the public key can always be derived from the private key and never the reverse
  • Separate signing, key transport and key agreement as three distinct uses of a key pair
  • Describe what protects a TLS 1.3 session and what role the certificate key plays in it
  • Prove that a private key and a certificate correspond, using only local commands

Prerequisites

Verified against OpenSSL 3.5.x teaching target; 3.0+ minimum · OpenSSH 10.x teaching target; 8.2+ minimum for certificate workflows · OpenBao 2.6.x · Smallstep step-ca 0.30.x · Certbot / Pebble Certbot current release; Pebble 2.10.x ACME test server · Kubernetes (cross-course target) 1.36.x · PostgreSQL 17.x · 2026-08-26

Not yet marked complete on this device.

A key pair is a device for splitting one capability into two: the ability to prove something, which stays private, and the ability to check that proof, which you publish as widely as you like. Once you hold that split in your head, certificates, SSH trust, signed commits and workload identity all stop being separate topics and become the same topic wearing different file formats.

One key, derived from the other, in one direction only

The private key file is the whole key pair. When a tool asks for your public key it is not reading a second file that happens to be lying around; it recomputes the public half from the private half on demand. That is why extracting a public key needs no network, no certificate authority and no other input:

# Generate a P-256 key pair. The file holds the private key; the
# public half is derived from it whenever something asks for it.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out app.key
openssl pkey -in app.key -pubout > app.pub

The reverse computation is the hard problem the whole field rests on. Given app.pub there is no practical way to recover app.key, and every algorithm you will meet is a different bet about which mathematical problem stays hard. You do not need the mathematics. You need the operational consequence: app.pub is publishable and app.key is the asset. A private key that has been copied off its host, pasted into a chat window, or committed to a repository is compromised from that moment, whether or not anyone has used it.

Three jobs, and only one of them is common

People say “public key cryptography” and mean any of three quite different operations. Naming which one is in play removes most confusion in a design review.

  • Signing and verification. The private key produces a signature over a digest; anyone with the public key checks it. This is what a certificate authority does, what an SSH client does to authenticate, what Git commit signing does, and what every artifact signing scheme does. It is by far the most common use.
  • Key transport. The public key encrypts a small value, and only the private key can recover it. RSA can do this; elliptic curve signing keys cannot. It was how TLS worked for many years, and it is now largely historical because it offers no forward secrecy.
  • Key agreement. Two parties each contribute an ephemeral key pair, exchange public halves, and independently compute the same shared secret. Nothing is encrypted and nothing is transported. Diffie-Hellman and its elliptic curve form are this, and they are how session keys are established today.
flowchart TD
    A["Key pair"] --> B["Sign with private\nverify with public"]
    A --> C["Encrypt with public\ndecrypt with private"]
    A --> D["Agree a shared secret\nboth contribute a pair"]
    B --> E["Certificates, SSH auth,\nGit and artifact signing"]
    C --> F["Legacy key transport\nno forward secrecy"]
    D --> G["TLS and SSH session keys"]

The diagram is worth reading as a ranking. Signing is where an infrastructure engineer spends nearly all of their time, key agreement is what silently protects every session, and key transport is the one you will mostly encounter as something being removed from a configuration.

The misconception worth killing: certificates do not carry your traffic

The belief that a server certificate encrypts the connection is almost universal and it makes several real incidents hard to reason about. In TLS 1.3 the server’s certificate key decrypts nothing at all. The sequence is:

  1. Client and server exchange ephemeral public keys and each compute the same shared secret. Neither key is in the certificate.
  2. That shared secret is expanded into symmetric AEAD keys, which protect the rest of the handshake and all application data.
  3. The server proves it is entitled to the name in the certificate by signing the handshake transcript with the private key matching the certificate’s public key, in the CertificateVerify message.

The certificate’s job is binding a name to a public key so the client can check step 3. The confidentiality came from step 1. This is why forward secrecy exists: the ephemeral pairs are discarded when the connection ends, so an attacker who records traffic today and steals the server’s private key next year still cannot decrypt the recording. It is also why “we rotated the certificate, so the recorded traffic is safe” was never a correct statement about older key-transport suites and is a correct statement about the modern ones.

Proving a key and a certificate belong together

The most useful practical skill in this lesson is a two-command check that resolves a whole family of service startup failures. Because the public key is derived from the private key, and because the certificate embeds that same public key, hashing both and comparing is conclusive:

$ openssl pkey -in app.key -pubout | openssl sha256
SHA2-256(stdin)= 75061de3387b8969c6c33ba0931ec0e541ad4c90a4ee2ec3e734e031af66874b
$ openssl x509 -in app.crt -noout -pubkey | openssl sha256
SHA2-256(stdin)= 75061de3387b8969c6c33ba0931ec0e541ad4c90a4ee2ec3e734e031af66874b

Identical digests mean the certificate was issued for that key. Different digests mean the pair does not correspond, and no amount of restarting will help: the service is being asked to prove possession of a key it does not hold. This happens after a renewal that regenerated the key but deployed only the certificate, after a copy that picked up the wrong file from an archive directory, and after a configuration management run that templated two paths from different variables. The check works offline, needs no running service, and takes seconds.

Choosing an algorithm, and deciding where the private key lives

Selection, not implementation, is your job. Three families matter in practice. RSA is universally supported and has large keys and signatures; 2048 bits is the common floor and 3072 or 4096 is usual for certificate authority keys that must outlive their subordinates. Elliptic curve keys over P-256 or P-384 are smaller and faster for the same security margin and are the default choice for most new leaf certificates. Ed25519 is smaller again, has no parameter choices to get wrong, and is the right default for SSH.

Support is a real constraint and it changes. OpenSSH 10 removed DSA outright, and the key types the local binary will accept are not a matter of opinion:

ssh -Q key

The output on OpenSSH 10.2 lists ssh-ed25519, the NIST curve types, the security key variants, ssh-rsa and the corresponding certificate forms. There is no ssh-dss entry. Note that ssh-rsa there is a key type; the SHA-1 signature algorithm of the same name is a separate thing from the rsa-sha2-256 and rsa-sha2-512 signature algorithms that are the modern defaults.

Where the key lives is a bigger decision than which curve it uses. A key in a file is readable by anything that can read the file, which includes a backup job, a container image build, and an attacker with the service account. A key in a hardware module or a remote key service is used through an interface that signs on request and never exports the key, which converts theft of the key into abuse of an API call you can audit and revoke.

Production discipline

  1. Treat the private key file as the asset and the public key as documentation. Inventory where private keys exist. Publishing a public key is never an incident.
  2. Say which key. Incident notes, alerts and runbooks should name the key by role and by path, not by the word “key”.
  3. Generate keys where they will be used. A key generated on a laptop and copied to three servers has three custody problems and one audit trail.
  4. Prefer non-exportable key storage for anything long-lived. Certificate authority keys and SSH certificate authority keys are the first candidates, because their compromise is not a single-service event.
  5. Keep the correspondence check in your runbooks. Two commands eliminate the most common cause of a service that refuses to start after a certificate deployment.

Cross-course references

  • Linux for Production Sysadmins - Part XXVI (SSH) covers the key files, agent behaviour and permissions that decide who on a host can use a private key at all.
  • Kubernetes for Production Sysadmins - Part LXXVI (Certs) covers the cluster key pairs whose correspondence problems look exactly like the failure described in this lesson.
  • Git, CI/CD & GitOps for Infrastructure Engineers - Part LXIX (ArtifactSigning) covers the signing use of a key pair applied to build outputs rather than to network identity.

Quiz

Knowledge check · 4 questions

  1. Q1. In a TLS 1.3 session, what does the server's certificate private key actually do?

  2. Q2. You need the certificate to extract the public key that matches a private key file.

  3. Q3. Describe how you would prove, offline, that a private key and a certificate correspond.

  4. Q4. Diagnose the failure and describe the safe recovery.

    At 02:40 UTC a scheduled renewal replaced both files for api.example.com on web-01. The web server failed to reload and the service has been serving errors since. The on-call engineer has already restarted the process twice and is proposing to request a fresh certificate from the certificate authority.

Passing score: 75%. Answers are checked in this browser.