<!-- https://pkizerotohero.com/handbook/binding-identity/ | Markdown mirror of the HTML page | PKI Zero to Hero, by Duyutech BV -->

> Why public keys need a trusted link to a name: key substitution and man-in-the-middle, fingerprints over a second channel, TOFU, and certificates.

Source: https://pkizerotohero.com/handbook/binding-identity/ · Last reviewed: 2026-10-20

Part II: Proof · Chapter 7

# Whose key is it? Binding identity to keys

**In one sentence:**

Encryption and signatures only help if you use the right person's public key, so something you already trust must vouch that a key belongs to a name.

## Who is this for

- [Beginner](https://pkizerotohero.com/start/#beginner)
- [Developer](https://pkizerotohero.com/start/#developer)
- [IT ops](https://pkizerotohero.com/start/#itops)
- [Expert](https://pkizerotohero.com/start/#expert)
- [Leader](https://pkizerotohero.com/start/#leader)

Level: **Beginner**

- [New to this? Start with The idea](https://pkizerotohero.com/handbook/binding-identity/#the-idea)
- [Developer? Jump to How it really works](https://pkizerotohero.com/handbook/binding-identity/#how-it-really-works)
- [IT ops? At work](https://pkizerotohero.com/handbook/binding-identity/#at-work)
- [Leader? Why it matters](https://pkizerotohero.com/handbook/binding-identity/#why-it-matters-to-the-business)

## The idea

- Beginner

Every chapter so far has quietly assumed one thing: that Ken has **Rosa’s real public key**. [Key pairs](https://pkizerotohero.com/handbook/key-pairs/) let Ken encrypt to Rosa, and [digital signatures](https://pkizerotohero.com/handbook/digital-signatures/) let him check Rosa’s decrees. Both only work if the public key he uses really is Rosa’s.

Public keys are meant to be shared. That is their strength, and also their weakness: anyone can publish a key and put any name on it.

Here is what Mallory does. She makes her own key pair and pins her public key on the town noticeboard with the label “Rosa’s key”. Ken copies it, trusting the label. Now:

- **Ken encrypts a secret “to Rosa”.** It is really encrypted to Mallory’s public key. Mallory decrypts it with her private key and reads it. She can even encrypt it again with Rosa’s real key and send it on, so Rosa receives it and nobody notices.
- **Mallory signs a fake decree** with her own private key. Ken verifies it with “Rosa’s key” from the noticeboard, and the check says *valid*.

The maths worked perfectly both times. Nothing was cracked. Ken simply used the wrong key. This is called a [key substitution](https://pkizerotohero.com/handbook/glossary/#key-substitution), and an attacker who sits between two people and swaps keys or messages is a [man-in-the-middle](https://pkizerotohero.com/handbook/glossary/#man-in-the-middle).

You cannot spot the swap by looking. Public keys are long random-looking numbers, and Mallory’s looks just as genuine as Rosa’s. In the game, Mallory’s disguise as Rosa is perfect, down to the long black hair. As Rosa puts it: “She can copy my face. She can’t copy my private key.” But that only protects Rosa if Ken holds her *real* public key.

So the question becomes: **how do you know which key belongs to whom?** There are four answers in use today.

1. **Compare fingerprints over a second channel.** Rosa reads out her key’s [fingerprint](https://pkizerotohero.com/handbook/hashes/) in person or over a phone call to a number you already know. If it matches the key you have, the key is hers.
2. **Trust on first use.** Accept the key the first time, remember it, and raise an alarm if it ever changes. Simple, but the very first contact is unprotected.
3. **A web of trust.** People you know sign statements about other people’s keys, and you trust keys that friends have vouched for.
4. **A trusted authority vouches.** Someone everyone already trusts checks that the key belongs to the name, then signs a statement saying so. That signed statement is a [certificate](https://pkizerotohero.com/handbook/glossary/#certificate).

The fourth answer is what PKI, public key infrastructure, is built on. The rest of this handbook is about how it works and how it fails.

*Diagram: The noticeboard shows a key labelled Rosa's key, but it is really Mallory's public key. Ken encrypts to it. Mallory decrypts, reads the message, re-encrypts it to Rosa's real key and passes it on, so Rosa receives it and suspects nothing. Below, Ken compares the key's fingerprint with the one Rosa reads out in person: they do not match, marked with a cross.*

The encryption worked perfectly, but to Mallory's key. Comparing fingerprints over a trusted channel exposes the swap.

In the game

In the game: the noticeboard at the Town Gate

In Level 7, Ken finds that the “Rosa’s key” pinned on the Town Gate noticeboard is really Mallory’s. He proves it by comparing fingerprints with Rosa face to face, a channel Mallory cannot touch.

**Where the picture stops being true:** in real life you can almost never meet the owner of every key you use. You visit websites run by people you will never see. Checking fingerprints by hand does not scale, so the internet uses certificates signed by certificate authorities instead. And even a certificate only shows that a key belongs to a name. It does not show that the person behind the name is honest.

## How it really works

- Developer
- Expert

### What does a man-in-the-middle actually do?

An active attacker on the network path does not need to break any cryptography. In concept:

- When the two sides swap public keys, the attacker replaces each key with one of her own.
- Each side then encrypts to, or agrees a secret with, the attacker, believing it is the other side.
- The attacker decrypts, reads or changes the traffic, and re-encrypts it for the real recipient.

Both ends see working encryption. Unauthenticated [key exchange](https://pkizerotohero.com/handbook/key-exchange/) has exactly this weakness, which is why TLS signs the handshake with a certificate key. The SSH architecture document, [RFC 4251, section 9.3.4](https://www.rfc-editor.org/rfc/rfc4251#section-9.3.4), says it plainly: using SSH “without first verifying the association between the server host key and the server host name” is “vulnerable to man-in-the-middle attacks”.

The defence is always the same: **authenticate the key**, meaning check that the public key belongs to the name you expect before you rely on it.

### What does “binding a key to an identity” mean?

A binding is a statement “public key K belongs to name N”, plus a reason to believe it. The four methods differ in where that reason comes from:

| Method | Where the reason comes from | Scales? | Weak point |
| --- | --- | --- | --- |
| Fingerprint check | You compare the fingerprint over a second, trusted channel | No | People skip it |
| Trust on first use | The first key you saw for that name | Yes | The first connection is unprotected |
| Web of trust | Signatures from people you know (OpenPGP, [RFC 9580](https://www.rfc-editor.org/rfc/rfc9580)) | Partly | Hard to reason about; few people use it |
| Certificate authority | A signature from an authority already in your trust store | Yes | You trust every authority in that store |

SSH’s architecture describes the first two side by side. [RFC 4251, section 4.1](https://www.rfc-editor.org/rfc/rfc4251#section-4.1) offers either a local database that maps each host name to its key, or host keys “certified by a trusted certification authority”. It suggests fingerprints, which “can easily be verified by using telephone or other external communication channels”. [RFC 7435, section 2](https://www.rfc-editor.org/rfc/rfc7435#section-2) defines trust on first use: accept and store a key “without authenticating that assertion”, after which connections are “secure against an MiTM attack, if such an attack did not succeed during the vulnerable initial communication”.

### Why is comparing a fingerprint enough?

Comparing two full public keys by eye is error-prone. A fingerprint is the SHA-256 hash of the key, so comparing 32 bytes is just as good as comparing the whole key. An attacker cannot make a different key with the same SHA-256 fingerprint, because SHA-256 resists second preimages (see [hashes](https://pkizerotohero.com/handbook/hashes/)).

That guarantee covers the *whole* fingerprint. Checking only the first and last few characters leaves room for an attacker to generate keys until one looks similar. Compare every character, or let software compare them for you.

### What is a certificate, in one paragraph?

A certificate is a signed document that binds a public key to a name. It contains the name (the subject), the public key, the issuer’s name, a validity period and the issuer’s [digital signature](https://pkizerotohero.com/handbook/digital-signatures/) over all of it. [RFC 5280, section 4.1.1.3](https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.3) puts it this way: by signing, “the CA certifies the binding between the public key material and the subject of the certificate”. You check that signature with the CA’s public key, and you trust the CA’s public key because it is already in your trust store. The next chapter, [anatomy of an X.509 certificate](https://pkizerotohero.com/handbook/x509-certificates/), takes one apart field by field.

Three facts keep certificates in perspective:

- **A certificate does not encrypt anything.** It carries a public key and a signature. Encryption happens elsewhere, with keys agreed during the handshake.
- **A certificate is public.** Anyone can hold a copy. Only the matching private key proves you are the name in it.
- **A root is trusted because it is in your trust store,** not because it signed itself. A self-signed certificate proves nothing on its own. See [trust stores](https://pkizerotohero.com/handbook/trust-stores/).

### Where does trust start?

Every method needs at least one key you trusted *before* the conversation began: the CA root keys that shipped with your operating system or browser, the host keys in your SSH `known_hosts` file, or the signers you listed in an `allowed_signers` file. Cryptography can carry trust from one key to another, but it cannot create trust from nothing. Knowing where your starting points come from, and who can change them, is the most important question in PKI.

## At work

- Developer
- IT ops

### Check an SSH host key against a trusted source

SSH uses trust on first use by default. Before you accept a server’s key the first time, compare its fingerprint with one from a source you already trust. GitHub, for example, publishes its SSH host key fingerprints on its [documentation site](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints), which you reach over HTTPS. Fetch the keys the server presents and print their fingerprints:

```bash
ssh-keyscan github.com 2>/dev/null | ssh-keygen -lf -
```

```text
256 SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU github.com (ED25519)
3072 SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s github.com (RSA)
256 SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM github.com (ECDSA)
```

On 20 October 2026 all three matched the published values exactly. Note what made this check meaningful: `ssh-keyscan` used the same network an attacker might control, but the published fingerprints came over a *different* channel, an HTTPS page whose certificate your browser already checked. Trust came from somewhere else.

### When the key changes

Once a key is in `~/.ssh/known_hosts`, OpenSSH compares it on every connection. We put a wrong key for `github.com` into a test `known_hosts` file to show what a substituted key looks like (OpenSSH 9.9; paths shortened):

```text
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
Please contact your system administrator.
Add correct host key in ~/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in ~/.ssh/known_hosts:1
Host key for github.com has changed and you have requested strict checking.
Host key verification failed.
```

This is binding identity at work. Often the cause is harmless: the server was rebuilt and got a new key. But you cannot tell from the message. Confirm the new fingerprint through a separate channel, such as the server’s owner or its published fingerprints, before you remove the old entry with `ssh-keygen -R <host>`.

At scale, teams avoid this guesswork with **SSH certificates**, where an internal CA signs host and user keys ([`ssh-keygen` manual](https://man.openbsd.org/ssh-keygen.1), section “Certificates”), or with SSH fingerprints published in DNS and protected by DNSSEC ([RFC 4255](https://www.rfc-editor.org/rfc/rfc4255)).

### See the binding in a website certificate

For HTTPS, the browser makes the binding check for you on every connection, using certificates. You can see the binding with OpenSSL (certificate for `rfc-editor.org`, fetched on 20 October 2026):

```bash
openssl x509 -in site.pem -noout -subject -issuer -ext subjectAltName
```

```text
subject=CN=rfc-editor.org
issuer=C=US, O=Google Trust Services, CN=WE1
X509v3 Subject Alternative Name:
    DNS:rfc-editor.org, DNS:*.rfc-editor.org
```

Read it as one signed sentence: “The CA called *WE1* says that the public key in this certificate belongs to `rfc-editor.org` and `*.rfc-editor.org`.” Browsers match the hostname against the Subject Alternative Name list, not the CN; see [names and key usage](https://pkizerotohero.com/handbook/names-and-key-usage/). Open the sample certificate in the decoder and find the three parts of the binding: the names, the public key and the issuer’s signature.

*Interactive tool: Certificate decoder (runs in the browser at [/tools/decoder/](https://pkizerotohero.com/tools/decoder/))*

### When the binding check fails

Many certificate errors are this chapter’s check failing:

- [`NET::ERR_CERT_AUTHORITY_INVALID`](https://pkizerotohero.com/errors/chrome-err-cert-authority-invalid/) and [`x509: certificate signed by unknown authority`](https://pkizerotohero.com/errors/go-x509-unknown-authority/): nobody your client trusts vouched for this key.
- [`NET::ERR_CERT_COMMON_NAME_INVALID`](https://pkizerotohero.com/errors/chrome-err-cert-common-name-invalid/): someone vouched for this key, but for a different name.

Warning

Turning off verification removes exactly this check

Options such as `curl -k`, `--insecure`, `verify=False` in Python or `NODE_TLS_REJECT_UNAUTHORIZED=0` keep the encryption but stop checking whose key it is. The connection is then encrypted to whoever answered, which is precisely the man-in-the-middle situation in this chapter. Fix the trust instead: install the right CA certificate, send the full chain, or correct the name.

## Common mistakes

- **“Encryption tells me who I am talking to.”** It does not. Encryption to the wrong key is still encryption. Identity comes from authenticating the key.
- **“A key labelled ‘Rosa’ is Rosa’s key.”** Labels are free. Anyone can attach any name to any public key. Only a check through something you already trust makes the link.
- **“The padlock means the website is honest.”** It means the connection goes to the holder of a key that a trusted CA bound to that name. A scam site can have a valid certificate for its own scam name.
- **“A self-signed certificate is trustworthy because it signed itself.”** Signing yourself proves only that you hold your own key. A root CA is trusted because it is already in your trust store.
- **“Comparing the first few characters of a fingerprint is enough.”** Compare the whole fingerprint, or let software compare it.
- **“The SSH warning is always just a reinstall.”** Often it is, but the warning exists because it might not be. Confirm the new key out of band before accepting it.

## Why it matters to the business

- Leader

Why it matters to the business

Identity is the hard part of encryption

Almost every encrypted connection your organisation makes depends on one question: is this really the other party’s key? When the answer is wrong, encryption still “works”, but to the attacker. Certificates and certificate authorities answer that question at scale, which is why the trust stores on your devices, your internal CAs and your SSH key practices are security decisions, not plumbing. Ask your teams who decides which CAs your systems trust, how server identities are verified for SSH and internal services, and whether any software runs with certificate verification turned off.

## Check yourself

Check yourself

Mallory pins her own public key on the noticeboard labelled 'Rosa's key'. Ken uses it to encrypt a secret for Rosa. What happens?

1. Nobody can read it, because the encryption is strong
2. Mallory can read it: the encryption worked, but to her key
3. Rosa can read it, because the key has her name on it

Show answer

Answer B Mallory can read it: the encryption worked, but to her key

What happened

Ken encrypted to Mallory's public key, so Mallory's private key decrypts it.

Why

The maths does exactly what it should. The failure is the binding: Ken never checked that the key belonged to Rosa.

The rule

Encryption and signatures are only as good as the link between a public key and a name. Check whose key it is.

Check yourself

Your SSH client warns that the remote host identification has changed. What is the best first step?

1. Remove the old entry and connect, because servers get rebuilt all the time
2. Confirm the new fingerprint through a separate trusted channel, such as the server's owner or its published fingerprints, before accepting it
3. Turn off host key checking for that server

Show answer

Answer B Confirm the new fingerprint through a separate trusted channel, such as the server's owner or its published fingerprints, before accepting it

What happened

The server presented a different key from the one stored for that name.

Why

A rebuilt server and a man-in-the-middle produce the same warning. Only a check over a channel the attacker cannot control tells them apart.

The rule

When a key changes, verify the new key out of band before you trust it.

Check yourself

What does a certificate add that a bare public key does not?

1. It encrypts the connection
2. A signed statement, from an authority you already trust, that this public key belongs to this name
3. Proof that the owner of the key is honest

Show answer

Answer B A signed statement, from an authority you already trust, that this public key belongs to this name

What happened

A certificate binds a public key to a name with the issuer's signature.

Why

You verify that signature with a key already in your trust store, so the binding inherits trust you already had. Certificates do not encrypt anything and say nothing about honesty.

The rule

A certificate is a signed binding of a name to a public key, trusted because its issuer is trusted.

## Go deeper

- [RFC 4251, sections 4.1 and 9.3.4](https://www.rfc-editor.org/rfc/rfc4251#section-4.1): SSH’s two trust models and its own warning about man-in-the-middle attacks.
- [RFC 7435, section 2](https://www.rfc-editor.org/rfc/rfc7435#section-2): the definition of trust on first use.
- [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280): the internet profile of X.509 certificates, which bind keys to names.
- [RFC 4255](https://www.rfc-editor.org/rfc/rfc4255): publishing SSH host key fingerprints in DNS, protected by DNSSEC.
- [GitHub’s SSH key fingerprints](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints): a real example of publishing fingerprints over a second channel.
- [OpenSSH `ssh-keygen` manual](https://man.openbsd.org/ssh-keygen.1): fingerprints, `known_hosts` management and SSH certificates.

Short on time? The crash course covers this chapter and the next in [Lesson 4: Whose key is it?](https://pkizerotohero.com/course/whose-key-is-it/).

**Early edition.** Checked against the standards; an independent expert review is in progress. Found a mistake? [Tell us](https://pkizerotohero.com/contact/?topic=content-error&page=/handbook/binding-identity/).

Last reviewed 20 October 2026Edition 0.9

## Keep going

Crash course: [Lesson 4: Whose key is it?](https://pkizerotohero.com/course/whose-key-is-it/)

### Error pages for this chapter

- [NET::ERR\_CERT\_AUTHORITY\_INVALID](https://pkizerotohero.com/errors/chrome-err-cert-authority-invalid/)
- [x509: certificate signed by unknown authority](https://pkizerotohero.com/errors/go-x509-unknown-authority/)

### How-to guides

- [How to use SSH certificates instead of known\_hosts](https://pkizerotohero.com/guides/ssh-certificates/)

### Tools

- [Certificate decoder](https://pkizerotohero.com/tools/decoder/): Paste a PEM certificate and read every field in plain words.

### Topics

- [Certificates](https://pkizerotohero.com/topics/certificates/)
- [Chains and trust stores](https://pkizerotohero.com/topics/chains-and-trust/)
- [Hashes and signatures](https://pkizerotohero.com/topics/signing/)
