How SSH Authenticates

How SSH Authenticates a Session

An SSH connection authenticates twice, in opposite directions. First the server proves who it is with its host key; only then does the user prove who they are, with a key or a password, inside an encrypted channel.

The stages of an SSH connection, from TCP handshake to a running command
The stages of an SSH connection, from TCP handshake to a running command

The key exchange gives both sides a secret that never crossed the wire, and the session keys derive from it. Since OpenSSH 10.0 23,707 the default is mlkem768x25519-sha256, a hybrid of post-quantum ML-KEM and classical X25519, so traffic recorded today stays safe against a future quantum computer. The server signs the exchange with its host key, which the client checks against ~/.ssh/known_hosts, asking you on a first connection.

With the publickey method, the client signs data unique to this session with your private key, and the server verifies it against the public key in the account's ~/.ssh/authorized_keys. The private key never leaves your machine, and a captured signature is useless in any other session. ssh -v shows every stage:

Watching a key-based login with ssh -vShell
ssh -v bk3ssh@localhost 'echo "logged in as $(whoami) on $(hostname)"'
Output
debug1: OpenSSH_10.2p1 Ubuntu-2ubuntu3.6, OpenSSL 3.5.5 27 Jan 2026
...
debug1: kex: algorithm: mlkem768x25519-sha256
debug1: kex: host key algorithm: ssh-ed25519
...
debug1: Host 'localhost' is known and matches the ED25519 host key.
...
debug1: Authentications that can continue: publickey,password
debug1: Offering public key: /home/dev/.ssh/id_ed25519 ED25519 SHA256:AS/gT7bk... agent
debug1: Server accepts key: /home/dev/.ssh/id_ed25519 ED25519 SHA256:AS/gT7bk... agent
Authenticated to localhost ([127.0.0.1]:22) using "publickey".
logged in as bk3ssh on PHANG

Older clients lag: Windows 11's bundled ssh.exe (OpenSSH_for_Windows_9.5p2) negotiated the classical curve25519-sha256 here. When a 10.1 or later client meets a classical-only server, it warns: connection is not using a post-quantum key exchange algorithm, unless you set KexAlgorithms yourself.