0

I've watched and read a lot about how SSH works, also the mathematics behind diffie-hellman etc.

The problem is that almost every YouTube video or article explains to a certain point where the key-exchange is done, meaning both client and server have the secret key, and the client verifies the public key. I just don't get what happens after that.

This is how I've learned SSH works (this is copied from another post on Servervault)

  1. SSHv2 Client: Key Exchange Init Several parameters negotiation, like compression and some crypto algorithms.

  2. SSHv2 Server: Key Exchange Init

  3. SSHv2 Client: Diffie-Hellman Key Exchange Init Negotiation of the DH parameters about mathematical group.

  4. SSHv2 Server: Diffie-Hellman Key Exchange Reply

  5. SSHv2 Client: Diffie-Hellman GEX Init First actual exchange of DH.

  6. SSHv2 Server: Diffie-Hellman GEX Reply After receiving this packet both peers know the secret key (gab) and establish a pseudo-secure channel with it (secure against casual eavesdropping, but not against man-in-the-middle-attacks).

All right, and this is where everything vague to me. Both client and server have the same secret key, but what happens after that? When I look in my .ssh folder, I see I have private and public keys, but those weren't even needed for these exchanges, except the Ephemeral Diffie-Hellman public keys and private keys the client and server "generated", but are only temporary and are all useless after the ssh connection (or even the DH exchange ) has ended.

I know that the server had also generated a private and public key pair (apart from the ephemeral ones), of which the public key is sent to the client in the SSH_MSG_KEX_ECDH_REPLY (along other things). So that public key, if it is the first time connecting to the SSH server (or generally if I've never stored it), I have the choice with the pop-up box to click accept to store that public key. So the client and server now have the same public keys (the client stored it), the server still has a private key. The messages being sent are being encrypted and decrypted by using the symmetrical shared secret keys. The connection ends, and those secret keys will be removed.

What if I connect again to the ssh server, will the diffie-hellman exchange happen the exact same way, but right now without the pop-up box?

Did only the server generate a key pair (not talking about ephemeral for diffie-hellman), if not what is it used for client-side?

Why do I somehow have a private key in my .ssh folder when I'm the client and it is password-locked?

Is the key pair (not ephemeral) generated by the server an RSA key pair?

How and for what is the private key used of the client, does the client generate the private key himself, and does he also have a public key?

I hope someone can clarify some of the concepts for me, I think I'm just thinking RSA out of the picture or something, it's really weird how the client can suddenly have a private key. It would also be really useful if someone could recommend me some resources to read further in depth about this matter, especiallly how Diffie-Hellman and RSA both fit together and about the temporary private and public keys.

I really appreciate any answer, have an amazing day!

1 Answers1

0

TLDR: SSH uses multiple algorithms to provide multiple security services

As summarized in rfc4251 section 1

   Secure Shell (SSH) is a protocol for secure remote login and other
   secure network services over an insecure network.  It consists of
   three major components:

   o  The Transport Layer Protocol [SSH-TRANS] provides server
      authentication, confidentiality, and integrity.  It may optionally
      also provide compression.  The transport layer will typically be
      run over a TCP/IP connection, but might also be used on top of any
      other reliable data stream.

   o  The User Authentication Protocol [SSH-USERAUTH] authenticates the
      client-side user to the server.  It runs over the transport layer
      protocol.

   o  The Connection Protocol [SSH-CONNECT] multiplexes the encrypted
      tunnel into several logical channels.  It runs over the user
      authentication protocol.

Specifically

  • confidentiality and integrity of data -- including (Perfect) Forward Secrecy, a term which was not well known and widely used in 2005 when 4251 was written -- is provided by ephemeral Diffie-Hellman key-agreement combined with symmetric encryption and MAC algorithm(s). Originally encryption and MAC were separate, but recent practice was been to combine them into 'authenticated encryption' algorithms such as AES-GCM and ChaCha20/Poly1305, which are often more specifically called Authenticated Encryption with Additional Data (AEAD). But note 'authenticated' for AE/AEAD is different from the authentications below.

  • server (called host in the protocol) authentication is provided by a public-key signature algorithm; originally this was RSA or DSA, but over the years ECDSA (restricted to P-256, P-384, P-521) and Ed25519 were added, and in the past few years OpenSSH (the most widely used implementation and therefore influential on what others do) disabled DSA and restricted RSA; you can find many questions on several Stacks on the theme "why did my SSH or something I use that is based on SSH stop working" where the answer turns out to be "you were using DSA (aka ssh-dss) or the old form of RSA (similarly ssh-rsa) and OpenSSH changed".

    Host auth is actually done as part of the key-exchange protocol, although it isn't strictly part of the key-exchange algorithm, and (thus) described in RFC4253. 4251 states it as 'SHOULD' but in practice it has become 'MUST'; implementations today assume it and probably won't work without. The serverfault answer you link doesn't mention it, but the last KEX reply includes the host signature; this is DHGEX_REPLY (the 6th packet) when DHGEX is used as shown in the serverfault A you link and specified RFC4419, or DH_REPLY (the 4th packet) for the 'basic' DH schemes defined in RFC4253 section 8.

    For best security the host (server) key should be configured manually or at least out-of-band on the client before it connects to the server. However, this would require, like, inconvenience, or even work, so in practice nobody does it except the one in ten zillion people who is a total security freak. Okay, maybe two. In practice nearly everybody uses 'trust on first use' (TOFU): when the client connects to a server/host for the first time it displays a 'fingerprint' (hash) of the host key and allows the user to 'verify' it; in practice users always click (or whatever) "just connect me to the expletive-deleted host no matter who it is, I don't care if it's an imposter that will steal, corrupt or destroy my data". The client then remembers this key linked to the host identity and on any subsequent connection if a different key is received from what should be the same host gives an error -- which may indicate a (delayed) attack, but also occurs and causes consternation if say you use cloud or virtual machines that are (frequently) redeployed, scaled, and/or moved, or you change the software on the host, or any number of legitimate things.

  • client (called user) authentication can be done several ways (and sometimes more than one way, aka multifactor authentication), but a very common one is the same kind(s) of public-key signature as for server authentication.

    User auth is done as a separate step after key-exchange is complete -- and thus will appear in a wireshark trace as unrecognizable encrypted data -- and publickey user auth is defined in RFC4252 section 7. OpenSSH definitely, and other implementations AFAIK, requires a user key to be configured on the host before it can be used; this is fairly often done by authenticating (aka logging-in) the first time using a (manually-entered) password, and using that connection to configure the publickey which is used on subsequent connections. (The popular ssh-copy-id script automates this process, but underneath it does what I described.) Other approaches are possible, like ansible or kubernetes or such 'injecting' the appropriate key when the host is deployed.

What if I connect again to the ssh server, will the diffie-hellman exchange happen the exact same way, but right now without the pop-up box?

Not quite exactly. There will be a new DH-exchange using the same protocol but different keys (that's what 'ephemeral' means). The host will normally sign with the same host key, and your client will accept it without a warning (which might or might not be a pop-up depending on the software). However if the host key has changed, as above, you will get at least a warning and likely an error.

Did only the server generate a key pair (not talking about ephemeral for diffie-hellman), if not what is it used for client-side?

The server will have at least one authentication (longterm) keypair; commonly it will have one for each supported algorithm, which nowadays is 3 or 4. But it will only send your client the one that is highest in the client's preference list, which will normally remain the same unless you change software. A semi-exception is the ssh-keyscan program provided by OpenSSH; that (except in ancient versions) alters the preference list to elicit all or nearly all host keys.

Why do I somehow have a private key in my .ssh folder when I'm the client and it is password-locked?

You apparently are using OpenSSH, or something built on OpenSSH, or something designed to be compatible with OpenSSH. The OpenSSH or compatible client uses the subdirectory .ssh in your home directory to contain several things, including any key(s) you have for user/client publickey authentication. OpenSSH itself will not generate these keys automatically, you must run ssh-keygen, but other software may think it is 'helpful' to create a key for you. However it should not do so without letting you choose, or at least know, the password. If you do know or find out the password, and that key's publickey is or has already been configured on the host(s) you want to connect to, you can use it for client/user auth to that/those host(s).

Is the key pair (not ephemeral) generated by the server an RSA key pair?

As above, it can be any supported algorithm including at least RSA, DSA (but not in recent OpenSSH by default), ECDSA, Ed25519.

How and for what is the private key used of the client, does the client generate the private key himself, and does he also have a public key?

A client/user key is used for client/user auth as above. Best security practice is that the user should generate their own key(s) and no one else should ever see them, but you need to be able to correctly follow instructions often with 3 or 4 steps, so organizations with lots of people who can't do that without hours of hand-holding may decide it's cheaper to centralize this. Somewhat similarly, some software may decide the 'technical details' of security are too confusing for you and do this itself, and if what the programmer decided to do isn't what you wanted, too sad.

Privatekey files used by OpenSSH always include the publickey, although the publickey is sometimes copied to a separate file e.g. id_rsa.pub for id_rsa to make it easier to access; this is rarely necessary since the switch to default 'new format' privatekey files in OpenSSH 7.8 (2018-08). If you do need or want a missing publickey file, you can regenerate it with ssh-keygen -y; see the man page.

dave_thompson_085
  • 2,910
  • 1
  • 15
  • 18