A particular server I need to interact with has an ancient or crippled sshd installed, and only supports SHA1 algorithms for key exchange. From information in the Snowden documents, I am leery that keys exchanged with servers with weak key exchange algorithms may be intercepted.

I keep a separate identity that I use with only with this server, and have a specific ~/.ssh/config entry to use that identity when connecting; and my machine-wide ssh_config does not permit the insecure key exchange algorithms.

However, if I have added my regular key to ssh-agent, it appears that my hopefully-more-secure key will still get sent over the potentially insecure key exchange.

Is there some way to further secure my configuration, so that I can prevent a key that I want to keep safe and private from being transmitted with a leaky key exchange algorithm?

If not, should there be? It seems that part of the agent contract is "all of these key exchange algorithms are absolutely 100% secure, so its ok to send any key." Since the key exchange algorithms are not all secure, this is (is it?) a problem.

While key exchange algorithms can be locked down at the machine level, this does not always work in practice, and its pretty easy to accidentally/intentionally override this in per-user config. Is there (or again, should there be) a way to configure "identity XYZ may only be used with KexAlgorithms/Ciphers/MACs?"

Gory Details:

I have an rsa identity id_insecure that I want to use with the insecure server, and an ed25519 identity id_secure that I use by default.

To avoid some potentially weak key exchange algorithms, my /etc/ssh_config contains:

Host *
    KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256

To allow access to the insecure server, since they cannot agree on a key exchange algorithm with the above setting, my ~/.ssh/config contains:

Host insecure_server
    IdentityFile path_to/id_insecure
    KexAlgorithms diffie-hellman-group14-sha1,and-some-other-icky-sha1-algorithms

However, if I load up id_secure into my SSH agent, and ssh -vvv insecure_server, the output will contain

debug1: Offering ED25519 public key: path_to/id_secure
debug3: send_pubkey_test
debug2: we sent a publickey packet, wait for reply
debug1: Authentications that can continue: ...

My understanding is that I have just sent my id_secure identity using the diffie-hellman-group14-sha1 key exchange algorithm, which is not as secure as once thought. If I'm mistaken about what is being passed around... I'd also find that to be valuable information.

2 Answers 2


You have several misconceptions here.

First, the whole point of a public/private keypair is that you don't send the private key to the server. The only thing your key is used for is signing messages; the server doesn't get your private key at any point during the SSH protocol. Even if you use agent forwarding (which lets you login to other servers from the first one using your key), the server doesn't get your private key: it just passes things on to ssh-agent on your computer, which signs them and sends the signature back to the first server to send on down the line.

Second, "key exchange" in this context doesn't mean "pass around keys," it means "establish a shared secret." The way Diffie-Hellman works is that the client and the server work out a new key, which is completely unrelated to any keys they might have had before. Long-term keys (i.e. the keypairs that are stored in files) are just used to sign elements of the key exchange, so that you know you're talking to the server you think you're talking to.

Third, key exchange in SSH has nothing at all to do with client keys (id_rsa and similar). The server authenticates itself during key exchange using the host key, but client authentication doesn't happen during key exchange. All a client key is used for is to sign a particular string after the key exchange (and after you've sent the username you want to log in to), in order to prove you can sign things with a private key corresponding to an authorized public key for that user. Key exchange algorithms have nothing to do with client keys.

So, weak key exchange doesn't pose any problems at all for private key security. That security doesn't rely on strong key exchange. The only attack you could do is exploit agent forwarding, but that could only work if a) you enabled it in the first place and b) you're still connected (disconnecting = no more agent forwarding).

Fourth, I'm actually not aware of an issue with using SHA-1 for the exchange hash. SHA-1 is weak to collision attacks, which means it's easier than it should be to create two things that hash to the same value. But to successfully MITM the connection, you'd need a second preimage attack, which means creating a collision with something that you don't control. In a collision attack you control both halves of the collision, which is a problem if you're signing something and the attacker can control what you're signing, in which case the attacker could create a colliding pair, get you to sign one thing, and use that as a signature of the other thing. While it's generally better to move away from it, calling it insecure for cases that only need second-preimage resistance is a bit of a stretch.

  • Of course. Have been wrapping my head around the ed25519 is just faster/is faster and more secure arguments, and somehow I mixed the identity into the key exchange. Needed a bit more of a nudge than the usual "walk away and get some coffee"... thanks. I reserve the right to continue mistrusting SHA1 though :)
    – danwyand
    Jan 9, 2015 at 21:10
  • 1
    @danwyand Fair enough; it's certainly not a bad idea to try to move away from SHA-1 where you can.
    – cpast
    Jan 9, 2015 at 21:19

Understanding the Risk: Jump Host Access to Other Resources

However, if I have added my regular key to ssh-agent, it appears that my hopefully-more-secure key will still get sent over the potentially insecure key exchange.

Exposure of key material is not actually the risk in the scenario you describe. The main risk with agent forwarding is that anyone who can access your account and/or the socket connection on the remote server you're connected to has the ability to use your forwarded agent on that machine to make it a jump host to other resources using your privileges. In other words, the risk is not that they gain access to your secret key; it's that they can use your forwarded agent to expand their access to additional accounts, services, or hosts where agent-based authentication to your remote public key is sufficient to grant access.

Disable Persistent Connections and Agent Forwarding

If you don't fully trust the server you're connecting to, then you can turn off agent forwarding on a per-host basis using command-line flags or stored settings your ~/.ssh/config file. For example, here's a configuration where the default is to allow agent forwarding, but forwarding and connection sharing are turned off when connecting to a particular untrusted host:

Host untrusted-host.example.com
    ControlPersist              no
    ForwardAgent                no

Host *
    Compression                 yes
    ControlMaster               auto
    ControlPath                 ~/.ssh/main-%r@%h:%p
    ControlPersist              yes
    ForwardAgent                yes

Basically, anything defined by Host * is a default setting, while the settings for a specific host take precedence. In the example above, OpenSSH is configured to forward the ssh-agent socket by default, and to keep active connections open in the background to allow muxing SSH sessions. By turning off ControlPersist and ForwardAgent for the untrusted host, you override the defaults for that specific host.

All of these settings (and a lot more besides) are documented in man 5 ssh_config for OpenSSH. The OpenSSH command-line client also allows you to refine or override the configuration file options with -o flags as documented in man 1 ssh, but the configuration file documentation does a better job of explaining what each option actually does.

Other SSH clients will have other mechanisms for configuration, but any client that properly implements agent forwarding should work in a similar way even if the mechanisms for user configuration vary. This should at least get you pointed in the right direction, and empower you to decide whether or not to trust a given server with access to your forwarded agent.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .