When connecting to a server, you receive an error about cipher negotiation:
$ ssh user@legacy-server.example.com
no matching cipher found. Their offer: aes128-cbc,3des-cbc,blowfish-cbcOr the inverse from the server side:
sshd[12345]: no matching cipher found: client aes256-gcm@openssh.com server aes128-cbc,3des-cbcThis 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.AES-GCM - Authenticated encryption, very secure
- 2.Chacha20-Poly1305 - Fast on systems without AES hardware acceleration
- 3.AES-CTR - AES in counter mode
Older systems might only offer:
- 1.AES-CBC - AES in cipher block chaining mode (legacy)
- 2.3DES - Triple DES (deprecated, slow)
- 3.Blowfish - Legacy 64-bit block cipher (deprecated)
List Available Ciphers
On your client, see what ciphers you support:
ssh -Q cipherOutput includes:
aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
aes256-ctr
aes192-ctr
aes128-ctr
aes256-cbc
aes128-cbcOn the server, check what's configured:
sudo sshd -T | grep ciphersCheck Server's Offered Ciphers
Connect with verbose mode to see what the server offers:
ssh -vv user@legacy-server.example.com 2>&1 | grep "cipher"Look for:
debug2: ciphers ctos: aes128-cbc,3des-cbc,blowfish-cbc
debug2: ciphers stoc: aes128-cbc,3des-cbc,blowfish-cbcThis shows the server only supports legacy CBC ciphers.
Enable Legacy Ciphers (Quick Fix)
To connect to a legacy server, explicitly enable older ciphers:
ssh -c aes128-cbc,aes256-cbc user@legacy-server.example.comOr specify multiple ciphers in order of preference:
ssh -c aes256-gcm@openssh.com,aes128-ctr,aes256-cbc,aes128-cbc user@legacy-server.example.comFor a permanent fix on that server, add to ~/.ssh/config:
Host legacy-server.example.com
Ciphers aes256-gcm@openssh.com,aes128-ctr,aes256-cbc,aes128-cbcUpdate Server Ciphers (Recommended)
On the server, enable modern ciphers. Edit /etc/ssh/sshd_config:
sudo nano /etc/ssh/sshd_configAdd or modify the Ciphers line:
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctrInclude legacy ciphers only if necessary for old clients:
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-ctr,aes256-cbc,aes128-cbcRestart SSHD:
sudo systemctl restart sshdCheck Client Configuration
Your client might have restrictive cipher settings. Check:
cat ~/.ssh/config | grep -i cipherAnd the system-wide config:
cat /etc/ssh/ssh_config | grep -i cipherComment out or update any restrictive cipher lines.
Verify Cipher Negotiation
After making changes, verify with verbose output:
ssh -vv user@server.example.com 2>&1 | grep -i "newkeys"Look for:
debug2: setting up keys: aes256-ctr
debug1: SSH2_MSG_NEWKEYS receivedThis 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:
ssh -c aes256-gcm@openssh.com user@server.example.com -v 2>&1 | grep "cipher"If it fails, try the next:
ssh -c aes256-ctr user@server.example.com
ssh -c aes128-ctr user@server.example.comOpenSSH 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:
ssh -o Ciphers="aes128-cbc,3des-cbc" -o KexAlgorithms="diffie-hellman-group1-sha1" user@ancient-server.example.comIn ~/.ssh/config:
Host ancient-server.example.com
Ciphers aes128-cbc,3des-cbc
KexAlgorithms diffie-hellman-group1-sha1
HostKeyAlgorithms ssh-rsaUpgrade 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.Building OpenSSH from source
- 2.Using a proxy or jump host
- 3.Replacing the legacy system
Resolution Checklist
- 1.Identify available client ciphers:
ssh -Q cipher - 2.Identify server-offered ciphers:
ssh -vv user@host 2>&1 | grep cipher - 3.Specify compatible cipher:
ssh -c cipher_name user@host - 4.Configure legacy support in
~/.ssh/config - 5.Update server cipher configuration for permanent fix
- 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.