The short answer
Generate an Ed25519 key unless something you must connect to cannot take it. OpenSSH has supported Ed25519 since version 6.5 (January 2014)[1], and since version 9.5 ssh-keygen generates Ed25519 keys by default, which the release notes explain with the small size of the public keys[1]. If you need a key for an old system, RSA works everywhere. ECDSA sits between the two and is rarely the right pick.
ssh-keygen -t ed25519 -C "you@laptop"
How the three differ in size
The clearest difference is how much text the public key is, because that is the line you paste into authorized_keys, a Git host's settings page or a ticket. Here are the lengths of the key lines OpenSSH writes, without a comment:
| Key | Command | Public key line |
|---|---|---|
| Ed25519 | ssh-keygen -t ed25519 | 80 characters |
| ECDSA P-256 | ssh-keygen -t ecdsa -b 256 | 160 characters |
| ECDSA P-521 | ssh-keygen -t ecdsa -b 521 | 252 characters |
| RSA 2048 | ssh-keygen -t rsa -b 2048 | 380 characters |
| RSA 3072 | ssh-keygen -t rsa -b 3072 | 552 characters |
| RSA 4096 | ssh-keygen -t rsa -b 4096 | 724 characters |
The Ed25519 line fits on one screen line and is easy to compare by eye. An RSA line is long enough to wrap over several lines of a terminal. Ed25519's is short because its public key is only 32 bytes[2].
Why Ed25519 is the default
RFC 8032, which specifies the algorithm, lists its advantages: high performance on a variety of platforms, small public keys and signatures, resilience against some side-channel attacks, and no need for a unique random number for each signature[2]. The last one matters in practice. Ed25519 signatures are deterministic, which protects against attacks that come from signing with bad randomness, the effects of which range up to full private key compromise, and the RFC adds that good random numbers can be surprisingly hard to get[2]. It is also designed to operate at around the 128-bit security level[2].
The same RFC says a sufficiently large quantum computer would be able to break Ed25519 and Ed448, and that projections for classical computers conclude Ed25519 is perfectly safe[2]. RSA and ECDSA face the same quantum limit, so it does not change which one to choose today.
When RSA is still right
Use RSA when the other end is too old for Ed25519: an SSH server older than OpenSSH 6.5, or software that parses only the older key types. A new RSA key of 3072 bits is a sensible choice. 2048 is still accepted, and 4096 makes the key line longer for a gain most people will not notice.
Old RSA keys are not a problem in themselves. OpenSSH disabled RSA signatures that use the SHA-1 hash by default because SHA-1 is broken, and says that for most users this is invisible: existing ssh-rsa keys keep working, using the stronger RSA signature algorithms where both ends support them[1]. You only need a new key if you want a smaller one or a modern default.
Where ECDSA fits
ECDSA keys use the NIST curves P-256, P-384 and P-521. They are shorter than RSA and widely supported. Ed25519 has the advantages listed above and spares you the choice between three curves. Pick ECDSA when a system supports it and does not support Ed25519. Otherwise use Ed25519 or RSA.
After you generate it
- Look at the fingerprint.
ssh-keygen -lf id_ed25519.pubprints the size, the fingerprint and the comment. The Key Inspector shows the same fingerprint and also reads PEM and JWK keys. - Protect the private key. Set a passphrase, or add one later with
ssh-keygen -p -f id_ed25519. The private file should be readable by you only:chmod 600 ~/.ssh/id_ed25519, or OpenSSH refuses to use the key. - Share only the
.pubfile. The public line is safe to paste anywhere. The private file never leaves your machine.
If you would rather not use a terminal, the Key Generator makes all of these key types in your browser and writes the OpenSSH files in the format ssh-keygen uses; its output is tested against ssh-keygen and OpenSSL. For a long-lived key on a production machine, generating it on that machine with ssh-keygen is still the better habit.
Both tools run in your browser. After the page has loaded they make no network requests, and your keys stay in the tab. You can check that yourself.