Skip to main content
ssh

SSH keys explained: Ed25519 vs ECDSA vs RSA, and the config that stops key roulette

For a new SSH key, use Ed25519 unless a legacy system cannot accept it. Then name the host in ~/.ssh/config instead of letting your agent guess which key to offer.

Thien Nguyen
By Thien Nguyen
Updated July 21, 2026 · 3 min read

For a new workstation key, generate Ed25519. It is compact, fast, and broadly supported by modern OpenSSH. Generate RSA 4096 only when a server, appliance, or old policy cannot accept Ed25519. ECDSA works, but it is rarely the clearest default when Ed25519 is available.

The choice in one table

AlgorithmUse it whenAvoid it when
Ed25519You control current OpenSSH clients and serversA legacy endpoint rejects it
RSA 4096You need compatibility with older SSH stacksYou are choosing it only because it is familiar
ECDSAA required environment explicitly standardises on itYou have no interoperability reason

The algorithm label is only one layer. A private key copied into chat, committed to a dotfiles repo, or left without a passphrase is still a compromised key.

Generate a key you can identify later

ssh-keygen -t ed25519 -a 100 -C "laptop-2026-work"

-a 100 raises the bcrypt KDF rounds used to protect the private key passphrase. The comment is not security metadata; it is an operational label that helps you remove the right key six months later.

Do not share the private file ending in no extension (for example id_ed25519). The .pub file is the one intended for servers, Git hosts, and authorized_keys.

Verify what you are actually installing

Before pasting a public key into a provider dashboard, inspect its fingerprint:

ssh-keygen -lf ~/.ssh/id_ed25519.pub

On a server, keep permissions strict enough that OpenSSH will trust them:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Then test with verbosity before declaring authentication broken:

ssh -vvv git@example.com

The useful lines say which identities the client offered and which one the server accepted. That beats repeatedly pressing Enter through a key-selection prompt and hoping the agent picks the right key.

Stop the agent from guessing: name the host

A generated key is only half the setup. Put the connection policy in ~/.ssh/config so ssh prod-api says what you mean instead of relying on whichever identity your agent happens to offer first:

Host prod-api
  HostName api.example.com
  User deploy
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes
  ServerAliveInterval 30

IdentitiesOnly yes is the line that matters on a machine with several loaded keys — without it, the client sprays every agent identity at the server and you get a confusing "Too many authentication failures" instead of a clean rejection.

SituationConfig choiceWhy
Work vs. personal Git hostSeparate Host alias per identityKeeps unrelated identities from ever being offered to the wrong host
Bastion hostProxyJump bastionAvoids a hand-written tunnel chain in every terminal tab
Temporary debug serverIts own Host aliasMakes the config diff — and later removal — obvious
ProductionStrictHostKeyChecking yesRefuses a changed host key instead of training the team to type "yes" through a warning

Never resolve an unknown-host-key warning with StrictHostKeyChecking no in shared or production config. Verify the server fingerprint through a separate channel — the SSH config builder generates the alias block above without a typo, but it can't verify the fingerprint for you.

Key hygiene that actually survives a team

Use one key per person and device, retain the public-key comment, and remove keys during offboarding. For high-value production access, consider short-lived SSH certificates rather than an ever-growing authorized_keys file. The win is revocation: deleting a single signer or certificate authority policy is more tractable than finding a copied public key across 80 hosts.

Ed25519 is the sensible default. The rest of the work is knowing where each key is authorised and being able to revoke it quickly.

References

Primary documentation and specifications checked when this article was last updated.

sshsecuritydeveloper-toolsconfiguration

Related articles

All articles