When connecting to a server, you receive an error about cipher negotiation:

bash
$ ssh user@legacy-server.example.com
no matching cipher found. Their offer: aes128-cbc,3des-cbc,blowfish-cbc

Or the inverse from the server side:

bash
sshd[12345]: no matching cipher found: client aes256-gcm@openssh.com server aes128-cbc,3des-cbc

This means your SSH client and server have no encryption algorithms in common. This typically happens when connecting between very old and very new systems.

Understand the Cipher Hierarchy

SSH uses symmetric ciphers to encrypt the data stream. Modern SSH prefers:

  1. 1.AES-GCM - Authenticated encryption, very secure
  2. 2.Chacha20-Poly1305 - Fast on systems without AES hardware acceleration
  3. 3.AES-CTR - AES in counter mode

Older systems might only offer:

  1. 1.AES-CBC - AES in cipher block chaining mode (legacy)
  2. 2.3DES - Triple DES (deprecated, slow)
  3. 3.Blowfish - Legacy 64-bit block cipher (deprecated)

List Available Ciphers

On your client, see what ciphers you support:

bash
ssh -Q cipher

Output includes:

bash
aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
aes256-ctr
aes192-ctr
aes128-ctr
aes256-cbc
aes128-cbc

On the server, check what's configured:

bash
sudo sshd -T | grep ciphers

Check Server's Offered Ciphers

Connect with verbose mode to see what the server offers:

bash
ssh -vv user@legacy-server.example.com 2>&1 | grep "cipher"

Look for:

bash
debug2: ciphers ctos: aes128-cbc,3des-cbc,blowfish-cbc
debug2: ciphers stoc: aes128-cbc,3des-cbc,blowfish-cbc

This shows the server only supports legacy CBC ciphers.

Enable Legacy Ciphers (Quick Fix)

To connect to a legacy server, explicitly enable older ciphers:

bash
ssh -c aes128-cbc,aes256-cbc user@legacy-server.example.com

Or specify multiple ciphers in order of preference:

bash
ssh -c aes256-gcm@openssh.com,aes128-ctr,aes256-cbc,aes128-cbc user@legacy-server.example.com

For a permanent fix on that server, add to ~/.ssh/config:

bash
Host legacy-server.example.com
    Ciphers aes256-gcm@openssh.com,aes128-ctr,aes256-cbc,aes128-cbc

On the server, enable modern ciphers. Edit /etc/ssh/sshd_config:

bash
sudo nano /etc/ssh/sshd_config

Add or modify the Ciphers line:

bash
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

Include legacy ciphers only if necessary for old clients:

bash
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-ctr,aes256-cbc,aes128-cbc

Restart SSHD:

bash
sudo systemctl restart sshd

Check Client Configuration

Your client might have restrictive cipher settings. Check:

bash
cat ~/.ssh/config | grep -i cipher

And the system-wide config:

bash
cat /etc/ssh/ssh_config | grep -i cipher

Comment out or update any restrictive cipher lines.

Verify Cipher Negotiation

After making changes, verify with verbose output:

bash
ssh -vv user@server.example.com 2>&1 | grep -i "newkeys"

Look for:

bash
debug2: setting up keys: aes256-ctr
debug1: SSH2_MSG_NEWKEYS received

This confirms successful cipher negotiation.

Security Considerations

Using weak ciphers has security implications:

  • CBC ciphers - Vulnerable to padding oracle attacks in some scenarios
  • 3DES - Vulnerable to Sweet32 birthday attack, very slow
  • Blowfish - Small 64-bit block size vulnerable to birthday attacks
  • RC4 - Deprecated due to biases in the keystream

If you must use weak ciphers, restrict them to specific legacy hosts:

``` # ~/.ssh/config Host legacy-server.example.com Ciphers aes256-cbc,aes128-cbc

Host * Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-ctr ```

Test Specific Ciphers

Test if a specific cipher works:

bash
ssh -c aes256-gcm@openssh.com user@server.example.com -v 2>&1 | grep "cipher"

If it fails, try the next:

bash
ssh -c aes256-ctr user@server.example.com
ssh -c aes128-ctr user@server.example.com

OpenSSH Version Differences

Different OpenSSH versions have different defaults:

  • OpenSSH 7.6+ - Disables CBC ciphers by default
  • OpenSSH 8.0+ - Disables blowfish, 3DES by default
  • OpenSSH 8.5+ - Disables rijndael-cbc by default

Check your versions:

```bash # Client ssh -V

# Server (if accessible) sshd -V ```

Fix for Very Old Servers

For servers running ancient SSH versions (pre-OpenSSH 5.0), you might need:

bash
ssh -o Ciphers="aes128-cbc,3des-cbc" -o KexAlgorithms="diffie-hellman-group1-sha1" user@ancient-server.example.com

In ~/.ssh/config:

bash
Host ancient-server.example.com
    Ciphers aes128-cbc,3des-cbc
    KexAlgorithms diffie-hellman-group1-sha1
    HostKeyAlgorithms ssh-rsa

Upgrade Legacy Systems

The best long-term solution is upgrading the legacy server:

```bash # Ubuntu/Debian sudo apt update && sudo apt install openssh-server

# RHEL/CentOS sudo yum update openssh-server ```

If the OS is too old for modern OpenSSH, consider:

  1. 1.Building OpenSSH from source
  2. 2.Using a proxy or jump host
  3. 3.Replacing the legacy system

Resolution Checklist

  1. 1.Identify available client ciphers: ssh -Q cipher
  2. 2.Identify server-offered ciphers: ssh -vv user@host 2>&1 | grep cipher
  3. 3.Specify compatible cipher: ssh -c cipher_name user@host
  4. 4.Configure legacy support in ~/.ssh/config
  5. 5.Update server cipher configuration for permanent fix
  6. 6.Plan upgrade for legacy systems using weak ciphers

Cipher mismatch errors usually indicate a significant version gap between client and server. While enabling legacy ciphers provides temporary access, plan to upgrade legacy systems for proper security.