Skip to content
ecdsa.com

Ed25519 vs RSA keys: which SSH key type to generate

For new SSH keys the answer has been Ed25519 for years. The remaining reasons to generate RSA are compatibility gaps, and they are getting rare.
ComparedEd25519RSA

Ed25519 vs RSA comes up most often when someone runs ssh-keygen and wonders which -t to pass. The same comparison applies to code and file signing. Ed25519 gives 128-bit security with tiny keys and fast, deterministic signatures; RSA gives universal compatibility at a much larger size and a slower, more fragile key generation.

At a glance

Ed25519RSA-3072
Securityabout 128 bitsabout 128 bits (RSA-2048: 112)
Private key32-byte seed3,072-bit modulus plus CRT values
Public key, raw32 bytes384-byte modulus plus exponent
OpenSSH .pub line (measured)86 bytes558 bytes
Signature64 bytes384 bytes
SSHSIG file for one signature (measured)294 bytes1,211 bytes
Key generationmicrosecondsabout 100 ms on average, highly variable
Sign / verify per second, OpenSSL 3.6.5about 60,000 / 25,000about 1,000 / 54,000
SSH algorithm namesssh-ed25519, sk-ssh-ed25519@openssh.comkey type ssh-rsa; signatures rsa-sha2-256, rsa-sha2-512
OpenSSH supportsince 6.5 (2014); default since 9.5 (2023)always
Deterministic signaturesYesYes for PKCS #1 v1.5, randomized for PSS
NIST IR 8547 (draft)disallowed after 2035RSA-2048 deprecated after 2030; all RSA disallowed after 2035

Measured with OpenSSH 10.3p1 and OpenSSL 3.6.5 on one core of an Apple M4 Max.

Sizes and speed

At the same 128-bit level, an Ed25519 public key is 32 bytes and an RSA-3072 modulus is 384. In SSH terms the difference shows up in authorized_keys, known_hosts, certificates and every handshake: an Ed25519 public key line is 86 bytes against 558 for RSA-3072, and a detached SSH signature file is 294 bytes against 1,211.

Speed is asymmetric. RSA verifies faster than Ed25519 (about 54,000 versus 25,000 operations per second here), but signs about 60 times slower, and key generation has to search for two large primes, which took about 100 ms per RSA-3072 key on average on this machine and can take much longer on small devices. For SSH servers that sign a handshake per connection, Ed25519 host keys cost less CPU; for users, both are instantaneous.

The script below generated the size figures in the table; it uses only OpenSSH.

Compare Ed25519 and RSA-3072 SSH keys and signatures
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
ssh-keygen -q -t ed25519 -N "" -C demo -f id_ed25519
ssh-keygen -q -t rsa -b 3072 -N "" -C demo -f id_rsa
for k in id_ed25519 id_rsa; do
  echo "$k.pub: $(wc -c < $k.pub | tr -d ' ') bytes"
  printf 'hello\n' > "msg-$k"
  ssh-keygen -q -Y sign -f "$k" -n file "msg-$k"
  echo "signature file: $(wc -c < "msg-$k.sig" | tr -d ' ') bytes"
done
cd / && rm -rf "$dir"
Output with OpenSSH 10.3p1
id_ed25519.pub: 86 bytes
signature file: 294 bytes
id_rsa.pub: 558 bytes
signature file: 1211 bytes

Robustness and failure modes

Ed25519 has few knobs: one curve, one hash, deterministic nonces, one signature encoding. There is no padding to choose and no weak parameter set to select by accident.

RSA's history is a list of parameter and padding mistakes. SSH's original ssh-rsa signature algorithm hashes with SHA-1, which is broken for chosen-prefix collisions; OpenSSH 8.8 (September 2021) disabled it by default, and RSA keys now sign with rsa-sha2-256 or rsa-sha2-512 (RFC 8332), which is automatic with any current client and server. Short keys are another trap: NIST has not allowed 1024-bit RSA for signatures since 2013, and 2048 bits is NIST's 112-bit level, which the draft NIST IR 8547 proposes to deprecate after 2030. Weak key generators have produced shared or structured primes (the ROCA flaw and keys factorable by batch GCD), a class of failure that does not exist for Ed25519 seeds as long as the random number generator works.

Compatibility

Ed25519 works with OpenSSH 6.5 and later, PuTTY, Windows' built-in OpenSSH, GitHub, GitLab, Bitbucket, most cloud consoles, Linux EC2 instances and Git's SSH commit signing. The notable gaps are Amazon EC2 Windows instances, whose key pairs must be RSA because the key decrypts the initial Administrator password, some network appliances and embedded SSH implementations, and very old enterprise software. FIDO-backed ed25519-sk keys need an authenticator that supports EdDSA; ecdsa-sk is the more widely supported hardware option.

RSA works everywhere SSH does, which is its only real advantage. For TLS certificates the situation is reversed: publicly trusted CAs issue RSA and ECDSA certificates but not Ed25519, so this comparison is about SSH and signing rather than HTTPS.

When to choose which

  • Personal SSH keys and CI deploy keys: Ed25519, protected with a passphrase or held on a security key (ssh-keygen -t ed25519-sk).
  • SSH host keys: offer Ed25519 first; keep an RSA host key (with rsa-sha2-* only) as long as old clients connect, and plan its removal.
  • Commit and file signing with SSH keys: Ed25519; signatures are a fifth of the size and verification is the same command.
  • Windows EC2 instances, legacy appliances, systems that cannot be updated: RSA-3072 or RSA-4096.
  • Hardware tokens in PIV mode: whatever the token supports, which is often RSA or ECDSA P-256 rather than Ed25519.
  • Long-term planning: neither survives a quantum computer; OpenSSH already protects session keys with a hybrid post-quantum key exchange, and OpenSSH 10.4 added an experimental composite ML-DSA-44 plus Ed25519 key type for signatures.

Migration notes

Replacing RSA keys with Ed25519 is a routine rotation.

  1. Generate the new key with ssh-keygen -t ed25519 -a 100 (more KDF rounds for the passphrase) or on a security key.
  2. Install it alongside the old key: append it to authorized_keys on each server, add it to your Git hosting account and to configuration management, and confirm that you can log in with ssh -i ~/.ssh/id_ed25519.
  3. For host keys, add HostKey /etc/ssh/ssh_host_ed25519_key to sshd_config; clients with UpdateHostKeys (on by default in current OpenSSH) learn the new key automatically, and known_hosts entries can be updated before the RSA key is removed.
  4. Remove the RSA key from authorized_keys, accounts and agents once nothing depends on it, and check logs for clients that still negotiate RSA.
  5. If you must keep RSA, make sure ssh-rsa (SHA-1) is not re-enabled anywhere: look for +ssh-rsa in HostKeyAlgorithms or PubkeyAcceptedAlgorithms. ssh -Q HostKeyAlgorithms lists what a client supports, nmap --script ssh2-enum-algos what a server offers, and the SSH key inspector shows a key's type, size and fingerprint.

References

All comparisons