You type ssh user@server, wait a second, and you're in a shell on a machine you've never touched. No password prompt if you've set up keys. It feels like magic, and most of us never bother to look at what's actually happening in that one second. It's worth unpacking, because SSH is solving two separate problems at once, and conflating them is where most misunderstandings about "key auth" come from.
The first problem: how do you and the server agree on a secret key to encrypt the session, over a network where anyone could be listening? The second problem: once you have an encrypted channel, how does the server confirm you are who you say you are, without you ever sending it something a listener could steal and reuse?
SSH solves the first with a key exchange. It solves the second with public-key authentication. They both involve "keys," but they're not the same keys, and they don't run for the same reason.
Before authentication even starts, the client and server run a Diffie-Hellman key exchange to agree on a shared secret — the session key that symmetrically encrypts everything from this point on. Neither side ever transmits this secret; each side computes it locally from its own private value and the other side's public value. Anyone sniffing the exchange sees the public values, not the secret.
This is why the handshake happens before you're ever asked to prove your identity. Authentication itself needs to be encrypted, or your username and any signed challenge would be visible to anyone on the wire.
.
Diffie-Hellman on its own only stops passive eavesdropping. It does nothing against a man-in-the-middle who intercepts the connection and runs the exchange twice — once with you, once with the real server. That's what the server's host key is for.
Every SSH server has a long-lived keypair, generated once. During the handshake, the server signs part of the exchange with its private host key, and the client checks that signature against the public key it has on file for that host — the one in ~/.ssh/known_hosts. The first time you connect to a new host, SSH shows you a fingerprint and asks you to trust it — that's "trust on first use." Every time after that, if the fingerprint doesn't match what's stored, SSH refuses the connection outright, because either the server was rebuilt or someone is intercepting you, and it can't tell you which.
This is the check people click through without reading. It's the entire reason SSH can detect a MITM at all.
.
With the channel encrypted and the server's identity verified, SSH moves to authenticating you. This is where your personal keypair — the one from ssh-keygen — comes in, and it's the part people usually mean by "SSH keys."
The server never sees your private key, and you never send it anything derived from it that could be replayed. Instead, the server sends a challenge, and your client signs it with your private key. The server checks that signature against the public key sitting in ~/.ssh/authorized_keys on its end. A valid signature is only possible if you hold the matching private key — there's no secret transmitted for someone to steal and reuse later.
That's the actual reason key auth is stronger than a password: a password is a shared secret you transmit, even if encrypted, and the server must store a way to check it. A signature is proof of possession that reveals nothing reusable, and the server only ever needs your public key.
.
1. TCP connect
2. Version exchange (client and server announce SSH versions)
3. Key exchange (Diffie-Hellman) -> shared session key negotiated
4. Server proves identity -> signs exchange with host private key,
client checks against known_hosts
5. Channel now encrypted with the session key
6. Client authenticates -> signs server's challenge with your
private key, server checks your
public key in authorized_keys
7. Shell / session starts
Every one of those steps guards against a different threat: eavesdropping, tampering, impersonation, replay. None of them is optional, and none of them is "the encryption part" on its own — they compose.
Once you see it this way, a few things people treat as separate SSH quirks turn out to be the same mechanism showing up twice:
REMOTE HOST IDENTIFICATION HAS CHANGED warning isn't SSH being paranoid — it's the host-key check failing, exactly as designed.ssh-copy-id only ever touches authorized_keys. Your private key never leaves your machine, by design — if it did, the whole possession-based proof falls apart.None of it is magic. It's two well-understood problems — secure channel, then identity — solved in sequence, and the whole thing fits in the second it takes to connect.