I am having problems understanding how ssh really works. I know it uses a public key cryptography to encrypt messages. However, I can ssh to a server without first generating a public/private key pair for me. I checked my .ssh folder and there is no .pub file there so I assume I have no public key that the server is aware of. So how can the server send me an encrypted message if I have no public key in the first place?
migrated from stackoverflow.com Dec 1 '11 at 23:07
This question came from our site for professional and enthusiast programmers.
Those are actually two different things. The public/private key pair you are talking about is for authentication.
When you connect to an ssh server your client and the server negotiate keys that they use for the encryption of their communication. Some algorithm that is derived from the Diffie-Hellmann key exchange algo. The same method is used when you access a page with your browser through the https-protocol.
If you are interested in the inner workings of the ssh protocol, you can check it out here. It's open ;)
edit: But I agree with Dennis, the crypto forum is the better place for this.
As @klaustopher describes, the SSH tunnel uses a Diffie-Hellman key exchange, to establish a shared secret between client and server; this shared secret is used with symmetric cryptography to encrypt and check integrity of all subsequently exchanged data.
As itself, DH+symmetric crypto is fine, but it does only half of the job. When the DH protocol has been executed, the both client and server know that they now have a secure tunnel with... someone. But they do not know who. They just know that this will be the same entity throughout the lifetime of the connection. So this is vulnerable to active attackers who impersonate the client, the server, or both. The famous Man-in-the-Middle attack is a case of double impersonation (the attacker acts as a fake server when he talks to the client, and as a fake client when he talks to the server).
To make a completely secure tunnel safe for transmitting confidential data and sensitive commands, the client and server must authenticate each other. In the first steps of the protocol, the server signs what he sends (his half of the Diffie-Hellman protocol); the client verifies that signature with regards to the known server public key (the one the client stores in
Thanks to the authentication of the server by the client (through the signature verification algorithm), the client knows that it can safely send his password in the tunnel.
The SSH protocol also supports signature-based client authentication. The DH and signature by the server are still done as previously. But the protocol then goes thus:
More or less the same thing happens with HTTPS. There are many local differences, e.g. the HTTPS client recognizes the server public key by validating a certificate instead of remembering it from a previous visit; and the password thing can take the form of actual Web pages; but the gist of the exchange is the same: the client makes sure that it talks to the right server by verifying its public key, and then the server makes sure that it talks to the right client (if the server is really interested in knowing who is the client) by running some sort of authentication protocol within the tunnel.