SSH encryption is a clever layered defense, not just a single lock, that makes your remote connections secure by combining public-key cryptography with symmetric encryption.
Let’s watch it in action. Imagine you’re on your local machine (client) and you want to connect to a remote server (server).
# On your local machine (client)
ssh user@your_server_ip_address
When you type this, a whole dance happens before you even see a shell prompt.
First, the client and server agree on which encryption algorithms they both support. They’ll exchange lists of ciphers (like AES-256-GCM), MAC algorithms (like HMAC-SHA2-256), and key exchange methods (like curve25519-sha256). This is the initial handshake.
Next, they perform a key exchange, typically using Diffie-Hellman (DH) or Elliptic Curve Diffie-Hellman (ECDH). This is where the magic of public-key cryptography comes in. Both sides generate temporary public/private key pairs. They exchange their public keys, but without ever sending their private keys over the wire. Using a mathematical trick, they can both independently derive the same shared secret key. This shared secret key is never transmitted directly, making it extremely difficult for an eavesdropper to figure out.
Example of ECDH (simplified concept, not actual SSH output):
- Client: Generates private key
c_privand public keyc_pub = G * c_priv(where G is a known base point on an elliptic curve). Sendsc_pubto the server. - Server: Generates private key
s_privand public keys_pub = G * s_priv. Sendss_pubto the client. - Client: Computes shared secret
S = c_priv * s_pub = c_priv * (G * s_priv) = G * c_priv * s_priv. - Server: Computes shared secret
S = s_priv * c_pub = s_priv * (G * c_priv) = G * s_priv * c_priv.
Both arrive at the same S without ever sharing c_priv or s_priv. This S is then used to derive the symmetric session keys.
Once they have this shared secret, they use a Key Derivation Function (KDF) to generate several symmetric encryption keys and MAC keys. These are session-specific keys, meaning they are unique to this particular SSH connection and are discarded when the connection closes. They derive keys for both directions: one for client-to-server, and one for server-to-client.
Now, the actual authentication happens. This is usually done via password or public-key authentication. If you’re using password authentication, your password is sent encrypted using the session keys just established. If you’re using public-key authentication, your client uses your private key (which never leaves your machine) to sign a challenge sent by the server. The server then verifies this signature using your public key (which it already has from ~/.ssh/authorized_keys on the server).
Finally, all subsequent data – your commands, the output from the server, file transfers – is encrypted using the symmetric session keys and authenticated with the MAC keys. This provides both confidentiality (no one can read your data) and integrity (no one can tamper with your data in transit without detection).
The most surprising thing about SSH encryption is that the initial, public-key based key exchange is often vulnerable to a "man-in-the-middle" attack if you blindly accept new host keys. SSH protects against this by having clients store the server’s public host key after the first successful connection. If the server later presents a different host key, the client will warn you, indicating that the server’s identity might have changed, possibly due to an attacker impersonating the server. You have to explicitly confirm to proceed, which is a crucial security check.
After this, you’re ready to explore more advanced SSH features like tunneling or agent forwarding.