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?
-
1This question would fit better on [crypto.stackexchange.com](http://crypto.stackexchange.com). – Dec 01 '11 at 20:27
-
@Dennis, this question is better suited here on security.sf. crypto.sf is about the mathematics behind cryptography. – Hendrik Brummermann Dec 02 '11 at 21:23
-
I had a rather hard time finding this, using SO as the main point of inquiry. All thanks to [@PeteScott's answer](http://stackoverflow.com/questions/24563677/best-practice-for-using-ssh-key-pair-with-different-groups) – hello_there_andy Feb 13 '17 at 21:00
2 Answers
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 .ssh/known_hosts
). Once the signature as been verified, the client knows that it is doing the DH key exchange with the genuine server, not an attacker posing as the intended server. This means that the client can safely send confidential data over the tunnel. In particular, once the DH has been done, the first exchanges go thus:
- (server) Ok, new client. We did the DH, I signed, you verified, you know I am the rightful server. Who are you ?
- (client) I'm Bob.
- (server) Prove it !
- (client) Here is my password: bobisthemasteroftheuniverse
- (server) Ok, I do know of a "Bob" user, and that's the right password. Welcome, Bob.
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:
- (server) Ok, new client. We did the DH, I signed, you verified, you know I am the rightful server. Who are you ?
- (client) I'm Bob. I have a key pair ! The public key id is: (...)
- (server) Yeah, let's see to that. Here is a bunch of random data, I challenge you to sign it: (...)
- (client) Here is a freshly generated signature on your challenge: (...)
- (server) Good. I know of a "Bob", his
.ssh/authorized_keys
contains a public key matching the id you sent, and your signature on my challenge verifies correctly with regards to that public key. Welcome, Bob.
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.
- 322,884
- 58
- 787
- 955
-
1As a side-note, SSHv2 uses a non-random message to be signed, see [here](http://security.stackexchange.com/q/23227/3272) – Tobias Kienzler Oct 12 '15 at 14:40
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-Hellman 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.
- 5,351
- 28
- 39
- 196
- 1
-
Thanks a lot. And sorry but I really didnt know there exists a crypto forum but thanks for your help :) – Dec 01 '11 at 20:52
-
-
I disagree that this should be on the crypto forum, or at least it should stay here as it's own copy. It was quite hard to find this, and I only found it since @PeteScott 's answer linked to this question on a [SO question](http://stackoverflow.com/questions/24563677/best-practice-for-using-ssh-key-pair-with-different-groups). PeteScott ' s answer would therefore need to change for other people like me to benefit from [this](http://security.stackexchange.com/questions/9366/ssh-public-private-key-pair/9389#9389) OP. How many other answers would need to change on other .sf sites... – hello_there_andy Feb 13 '17 at 21:06