Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

RSA vs Ed25519 for Keys

By Kokil Thapa | Last reviewed: September 2026

Choosing between RSA vs Ed25519 for keys shows up the moment you generate an SSH key, sign a JWT, or configure a CI deploy secret. RSA has been the default for decades and still works almost everywhere. Ed25519 is smaller, faster, and harder to misconfigure, but older clients and some enterprise tools reject it. This guide compares both algorithms with copy-paste commands, a decision table, and migration steps drawn from production Linux server administration and SSH key-only authentication work.

What is the difference between RSA and Ed25519 for cryptographic keys?

RSA and Ed25519 solve the same problem—public-key cryptography—but with different math and trade-offs. RSA relies on the difficulty of factoring large integers. Ed25519 is an Edwards-curve signature scheme defined in RFC 8032. You get a fixed 256-bit private key and a 512-byte signature.

RSA key sizes vary. A 2048-bit RSA key was once standard. Security guidance now treats 2048-bit RSA as a sunset size. A 4096-bit RSA key is safer but produces larger signatures and slower operations. Ed25519 keys are always 256 bits. There is no "pick a size" step that teams get wrong.

RSA vs Ed25519 for KeysRSAFactoring problem2048 or 4096 bitsPKCS#1 / PKCS#8Ed25519Edwards curveFixed 256 bitsRFC 8032 EdDSALegacy ubiquitySlower sign and verifyLarger keys and certsModern defaultFast operationsCompact signatures
RSA vs Ed25519 for keys: same use cases, different math, sizes, and performance profiles

Both algorithms provide digital signatures. Neither is a drop-in replacement for symmetric encryption like AES. You sign with a private key and verify with a public key. That pattern powers SSH host authentication, Git deploy keys, JWT bearer tokens, and TLS certificate chains.

The practical gap is ecosystem age. RSA predates cloud-native tooling by decades. Ed25519 arrived in OpenSSH 6.5 and is now the default in current OpenSSH releases documented at openssh.com. If your stack is Ubuntu 22.04 or 24.04 with current packages, Ed25519 support is already there.

Side-by-side numbers that matter in production

CriteriaRSA (4096-bit)Ed25519Verdict
Private key size (PEM, typical)~3.2 KB~400 bytesEd25519 wins
Signature size512 bytes64 bytesEd25519 wins
Sign/verify speedSlowerMuch fasterEd25519 wins
Legacy SSH client supportUniversalOpenSSH 6.5+ (2014)RSA wins
JWT libraries (2026)RS256 everywhereEdDSA growingRSA slight edge
TLS 1.3 cert chainsCommonRare in public CAsRSA for TLS certs
Misconfiguration riskWeak sizes, bad padding historyFixed parametersEd25519 wins
Quantum threat (long-term)Both need PQC migrationBoth need PQC migrationNeither is future-proof alone

For a deeper curve-family comparison beyond Ed25519 alone, see the related write-up on RSA vs ECC key sizes and trade-offs. Ed25519 is one Edwards-curve option, not the entire ECC landscape.

When should you choose Ed25519 over RSA for SSH keys?

Default to Ed25519 for new SSH keys on servers you control. I use Ed25519 on Ubuntu 22/24 hosts for client projects and sister-site deploy pipelines. The keys are short, operations are fast, and brute-force guessing a 256-bit seed is not a realistic threat model for SSH.

Keep RSA when a human or system on the other side cannot speak Ed25519. Examples include ancient embedded devices, some legacy VPN appliances, and corporate jump boxes stuck on decade-old OpenSSH builds. In those cases, generate RSA 4096—not 2048.

  • Use Ed25519 for developer laptops, GitHub/GitLab deploy keys, CI runners, and modern VPS instances.
  • Use RSA 4096 when ssh -V on the remote side is unknown and the business cannot tolerate lockout.
  • Retire RSA 2048 from production; rotate anything still at that size.
  • Never reuse the same key pair across personal and client infrastructure.

Pair key choice with hardening steps from SSH key auth, fail2ban, and port hardening. The algorithm is only one layer. Permissions on ~/.ssh, forced commands, and network restrictions matter just as much.

How do you generate and configure RSA vs Ed25519 keys in production?

Generation takes one command either way. Storage, permissions, and rotation policy matter more than the algorithm name on the tin.

ssh-keygen -t ed25519 -a 100 -C "deploy@production-2026" -f ~/.ssh/id_ed25519_prod

chmod 600 ~/.ssh/id_ed25519_prod
chmod 644 ~/.ssh/id_ed25519_prod.pub

ssh-copy-id -i ~/.ssh/id_ed25519_prod.pub deploy@203.0.113.10

The -a 100 flag sets bcrypt rounds for the optional passphrase KDF. Use a passphrase on keys that leave your machine. For fully automated CI, store the key in a secret manager and skip the passphrase—but never commit the private file to Git.

Generate RSA 4096 (legacy compatibility)

ssh-keygen -t rsa -b 4096 -a 100 -C "legacy-vendor-access" -f ~/.ssh/id_rsa4096_vendor

chmod 600 ~/.ssh/id_rsa4096_vendor

Force algorithm order in sshd_config

On servers you administer, prefer modern algorithms in /etc/ssh/sshd_config:

PubkeyAcceptedAlgorithms ssh-ed25519,ecdsa-sha2-nistp256,rsa-sha2-512,rsa-sha2-256
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

Reload SSH after changes: sudo systemctl reload ssh on Ubuntu. Test from a second session before closing your current one. Locking yourself out during a support and maintenance window is an expensive mistake.

SSH Key Auth Flowssh-keygenKey pairEd25519 or RSAauthorized_keysSSH login attemptSign challengePrivate keyServer verifiesPublic key matchFail closedWrong key or algorithm
SSH authentication with RSA vs Ed25519 for keys: generate, install public key, sign challenge, verify signature

authorized_keys hardening example

from="203.0.113.0/24",command="/usr/local/bin/deploy.sh",no-agent-forwarding,no-port-forwarding ssh-ed25519 AAAA... deploy@prod

Restrict source IPs and allowed commands per key. On legal-tech portals and client document systems I have shipped, separate deploy keys per environment stopped staging mistakes from touching production.

Which key type performs better for TLS, JWT, and API signing?

SSH is where Ed25519 shines first. Application-layer signing is messier because libraries and standards lag behind server defaults.

JWT and API tokens

Most Laravel and PHP APIs still default to RS256—RSA with SHA-256. It works with virtually every JWT library. EdDSA (Ed25519) appears as EdDSA or Ed25519 in JOSE headers and is supported in common PHP JWT packages when you opt in explicitly.

For greenfield API development, Ed25519 JWTs reduce token size on mobile clients. Before switching, audit every consumer: mobile apps, partner webhooks, and cached API gateways. A token nobody can verify is worse than a bulky RSA signature.

// Laravel config pattern — RS256 (widest compatibility)
'jwt' => [
    'algo' => env('JWT_ALGO', 'RS256'),
    'keys' => [
        'private' => storage_path('app/jwt/private.pem'),
        'public'  => storage_path('app/jwt/public.pem'),
    ],
],

Generate RSA key material for JWT with OpenSSL when RS256 is required:

openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem

For Ed25519 JWT keys, OpenSSL 3.x supports:

openssl genpkey -algorithm ED25519 -out ed25519-private.pem
openssl pkey -in ed25519-private.pem -pubout -out ed25519-public.pem

Read the related guide on API authentication: JWT vs session vs API keys before picking an algorithm in isolation. Key type is one piece of a broader auth design.

TLS certificates

Public certificate authorities still issue RSA and ECDSA P-256/P-384 chains far more often than pure Ed25519 end-entity certs. Browser trust stores and ACME clients on typical Ubuntu LAMP stacks expect RSA or ECDSA. Use Let's Encrypt ECDSA if you want smaller certs without fighting CA tooling.

Ed25519 belongs in your SSH and internal signing layers first. Public TLS is a separate decision tree.

Cloud secret managers and CI

Long-lived RSA or Ed25519 keys in CI pipelines are a recurring audit finding. Prefer OIDC federation so runners assume short-lived cloud roles. See deploy to AWS from GitHub Actions with OIDC (no keys) and workload identity federation without long-lived keys for patterns that remove static keys entirely.

When keys are unavoidable—legacy vendor SFTP, on-prem GitLab runners—store them in Azure Key Vault or AWS KMS with rotation policies. Never paste private PEM blocks into Slack or ticket comments.

Key Type Decision TreeNew key needed?SSH / Git deployJWT / app signingEd25519 defaultRSA 4096 if legacy clientRS256 if max compatEdDSA if all verifyPrefer OIDC / federation over static keys in CI
Decision tree for RSA vs Ed25519 for keys across SSH, JWT signing, and CI pipelines

How do you migrate from RSA to Ed25519 without breaking access?

Rotation fails when teams swap keys before confirming every client. Treat migration as a parallel-run exercise, not a Friday-afternoon config edit.

  1. Inventory every RSA key: developer laptops, CI secrets, cron SFTP jobs, vendor integrations, and backup scripts.
  2. Generate Ed25519 replacements with new filenames—do not overwrite existing RSA private keys yet.
  3. Append new public keys to authorized_keys alongside old RSA entries.
  4. Test login from each client identity: laptop, CI runner, monitoring probe.
  5. Update application configs that reference key paths (IdentityFile in SSH config, Deployer recipes, GitLab CI variables).
  6. Remove old RSA public keys only after a full business cycle with zero auth failures.
  7. Document the rotation date and owner in your runbook.

On Deployer 7 pipelines I maintain for sister legal-tech sites, the deploy user often has two keys during migration. That window typically lasts one to two weeks. Shorter windows risk weekend failures nobody notices until Monday.

SSH config for dual-key period

Host production
    HostName 203.0.113.10
    User deploy
    IdentityFile ~/.ssh/id_ed25519_prod
    IdentityFile ~/.ssh/id_rsa4096_legacy
    IdentitiesOnly yes

IdentitiesOnly yes stops SSH from offering every key in your agent. That prevents "too many authentication failures" lockouts on strict servers.

Common migration failures

Wrong permissions. Private keys must be 600. A world-readable private key makes sshd reject the login with a confusing error.

SELinux or AppArmor contexts. Restored keys from backup tarballs sometimes carry wrong labels. Check audit logs if auth silently fails.

Forced algorithm lists. If PubkeyAcceptedAlgorithms excludes ssh-ed25519, valid keys still fail. Align server and client configs.

Copied comment fields. The trailing comment on a public key is cosmetic. The key material must be one continuous line with no line breaks mid-base64.

For password hygiene during rotation, generate passphrases with the site password generator. Encode or inspect PEM blocks with the Base64 encoder and decoder when debugging corrupted keys.

RSA to Ed25519 MigrationRSA liveAdd Ed25519 pubParallel authTest allauthorized_keys holds BOTH keysRSA + Ed25519 until every client confirmedRemove RSA public keyEd25519 only — document rotation date
Safe RSA vs Ed25519 for keys migration: parallel keys, test every client, then retire RSA

Document-heavy client portals—such as those built for Mijar Law Associates or Adventure Third Pole Trek—rarely tolerate deploy outages. Parallel keys buy you time to catch edge cases without blocking lawyer uploads or booking payments.

Key Takeaways

  • Choose Ed25519 for new SSH and Git deploy keys on any stack running OpenSSH 6.5 or newer.
  • Keep RSA 4096 only for legacy clients that reject Ed25519; retire RSA 2048 immediately.
  • Use RS256 for JWTs when third-party verifiers are unknown; adopt EdDSA when you control every consumer.
  • Run parallel keys during migration, test each client identity, then remove old RSA public keys.
  • Prefer OIDC and short-lived tokens in CI over baking long-lived private keys into pipelines.
  • Align sshd algorithm lists with your chosen keys and fail closed on permission errors.

People Also Ask

Is Ed25519 more secure than RSA 4096?

Both provide strong classical security margins for typical web and SSH workloads in 2026. Ed25519 avoids weak-size mistakes because the parameters are fixed. RSA security depends heavily on using at least 3072 bits, preferably 4096, with modern padding. Ed25519 also sidesteps historical RSA implementation pitfalls. Neither algorithm addresses post-quantum threats; plan PQC migration separately at the infrastructure level.

Does GitHub support Ed25519 SSH keys?

Yes. GitHub, GitLab, and Bitbucket accept Ed25519 deploy and user keys. Generate with ssh-keygen -t ed25519 and paste the .pub file into your account SSH settings. If a corporate proxy strips unknown key types, fall back to RSA 4096 for that hop only.

Can I use Ed25519 for SSL/TLS website certificates?

Public CAs rarely issue Ed25519 TLS certificates today. Browsers and ACME tooling expect RSA or ECDSA chains. For HTTPS, use ECDSA P-256 from Let's Encrypt if you want smaller certs. Reserve Ed25519 for SSH, internal signing, and application tokens where you control both sides.

What happens if I only have RSA keys on my server?

Clients with Ed25519-only keys cannot authenticate until you add their public keys to authorized_keys. The server does not auto-convert algorithms. Either install the Ed25519 public key alongside existing RSA keys or generate a matching RSA key pair for that client. Check /var/log/auth.log for "Authentication refused: bad ownership or modes" before blaming the algorithm.

Pick the right key for the layer you are securing

RSA vs Ed25519 for keys is not a religious debate. It is a compatibility and operations question. Ed25519 is the better default for SSH and internal signing in 2026. RSA 4096 remains the fallback when something old refuses modern curves. JWT and TLS layers may still need RSA or ECDSA until your entire verifier chain catches up.

Start with an inventory of where keys live today—laptops, cron jobs, CI variables, vendor SFTP. Rotate the highest-risk static keys first. If you want help auditing SSH access, API signing, or deploy pipelines on a production Laravel or WordPress stack, contact us or explore custom software development options. For background on rate-limiting signed API traffic, see Laravel rate limiting with custom keys and read more from about me.

Frequently Asked Questions

Both provide public-key digital signatures for SSH, Git deploy keys, JWTs, and similar uses, but the math differs. RSA relies on factoring large integers with variable key sizes; 2048-bit RSA is now treated as a sunset size, while 4096-bit is safer but slower with larger signatures. Ed25519 is an Edwards-curve scheme in RFC 8032 with a fixed 256-bit private key and 64-byte signatures. Ed25519 avoids weak-size misconfiguration. RSA still wins on legacy SSH client support; Ed25519 wins on size, speed, and operational simplicity on modern stacks.

For new keys in 2026, prefer Ed25519. Keep RSA 4096 only where legacy clients, old HSMs, or PKCS#1-only tooling require it.

Both offer strong classical security for typical SSH and web workloads in 2026. Ed25519 uses fixed parameters, so teams cannot accidentally deploy undersized keys—a common RSA failure mode. RSA security depends on using at least 3072 bits, preferably 4096, with modern padding and avoiding historical implementation pitfalls. Neither algorithm alone addresses post-quantum threats; both will need a separate post-quantum cryptography migration plan at the infrastructure level when your threat model requires it.

Default to Ed25519 for SSH on servers you control, including developer laptops, GitHub and GitLab deploy keys, CI runners, and modern VPS instances on Ubuntu 22.04 or 24.04. Switch to RSA 4096 when the remote side cannot speak Ed25519—ancient embedded devices, legacy VPN appliances, corporate jump boxes on decade-old OpenSSH builds, or when ssh -V on the remote is unknown and lockout is unacceptable. Never generate new RSA 2048 keys for production; rotate anything still at that size immediately.

Ed25519: run ssh-keygen -t ed25519 -a 100 with a descriptive comment and output path, then chmod 600 the private key and 644 the public key before ssh-copy-id. RSA legacy: ssh-keygen -t rsa -b 4096 -a 100. The -a 100 flag sets bcrypt rounds for optional passphrase KDF—use a passphrase on keys that leave your machine. For automated CI, store keys in a secret manager without a passphrase, but never commit private PEM files to Git. Permissions and rotation policy matter more than the algorithm label.

On servers you administer, set PubkeyAcceptedAlgorithms to prefer modern options: ssh-ed25519, ecdsa-sha2-nistp256, rsa-sha2-512, rsa-sha2-256. Set HostKeyAlgorithms similarly with ssh-ed25519 first. Reload with sudo systemctl reload ssh on Ubuntu, then test from a second session before closing your current one. Locking yourself out during a maintenance window is costly. If PubkeyAcceptedAlgorithms excludes ssh-ed25519, valid Ed25519 keys still fail even when permissions are correct—align server and client algorithm lists before blaming the key type.

Yes. GitHub, GitLab, and Bitbucket accept Ed25519 keys. Generate with ssh-keygen -t ed25519 and add the .pub file to your account.

Most Laravel and PHP APIs still default to RS256—RSA with SHA-256—because virtually every JWT library verifies it. EdDSA or Ed25519 appears in JOSE headers and works in common PHP JWT packages when configured explicitly. Ed25519 JWTs reduce token size on mobile clients, but audit every consumer—mobile apps, partner webhooks, cached API gateways—before switching. A token nobody can verify is worse than a bulky RSA signature. Generate RS256 key material with OpenSSL genpkey for RSA 4096, or ED25519 with OpenSSL 3.x when you control both signing and verification sides.

Public CAs rarely issue Ed25519 TLS certificates. Browsers expect RSA or ECDSA chains instead.

A typical 4096-bit RSA private key in PEM is about 3.2 KB with 512-byte signatures; Ed25519 private keys are roughly 400 bytes with 64-byte signatures. Ed25519 signing and verification are much faster than RSA 4096. RSA retains universal legacy SSH client support; Ed25519 requires OpenSSH 6.5 or newer from 2014 onward. For JWT libraries in 2026, RS256 remains everywhere while EdDSA adoption is growing. Public TLS certificate chains from commercial CAs still favor RSA and ECDSA P-256 or P-384 over pure Ed25519 end-entity certs.

Treat migration as a parallel-run exercise, not a single config swap. Inventory every RSA key across laptops, CI secrets, cron SFTP jobs, vendor integrations, and backup scripts. Generate Ed25519 replacements with new filenames without overwriting existing private keys. Append new public keys to authorized_keys alongside old RSA entries, test each client identity, update IdentityFile paths in SSH config and Deployer or GitLab CI variables, then remove old RSA public keys only after a full business cycle with zero auth failures. A one-to-two-week dual-key window catches weekend edge cases.

Wrong permissions are the top culprit: private keys must be chmod 600 or sshd rejects login with confusing ownership or modes errors in auth.log. SELinux or AppArmor labels on restored backup keys can silently block auth. Forced algorithm lists in sshd_config that exclude ssh-ed25519 cause valid keys to fail. Public key material must be one continuous base64 line with no mid-line breaks—the trailing comment is cosmetic only. Use IdentitiesOnly yes in SSH config during dual-key periods to stop the agent offering every key and triggering too many authentication failures on strict servers.

Long-lived RSA or Ed25519 keys baked into CI pipelines are a recurring audit finding. Prefer OIDC federation so GitHub Actions or GitLab runners assume short-lived cloud roles without static private keys. When keys are unavoidable—for legacy vendor SFTP or on-prem GitLab runners—store them in Azure Key Vault or AWS KMS with rotation policies. Never paste private PEM blocks into Slack or ticket comments. On Deployer 7 pipelines for production Laravel stacks, separating deploy keys per environment prevents staging credentials from touching production document or booking systems.

Clients presenting Ed25519-only keys cannot authenticate until you add their Ed25519 public key to authorized_keys. Servers do not auto-convert between algorithms. Either install the Ed25519 public key alongside existing RSA entries or generate a matching RSA 4096 key pair for that client. Check /var/log/auth.log for bad ownership or modes errors before assuming the algorithm is wrong. Restrict keys in authorized_keys with from= source IP limits, forced command= paths, and no-agent-forwarding to reduce blast radius on legal-tech portals and client document systems.

Neither RSA nor Ed25519 is future-proof against large-scale quantum attacks on their underlying math. Both will require post-quantum cryptography migration at the infrastructure level for long-term confidentiality and signature guarantees. For 2026 SSH hardening, algorithm choice is primarily a compatibility and operations question: Ed25519 is the better default where OpenSSH 6.5 or newer is available, RSA 4096 remains the fallback for legacy tooling, and RS256 or ECDSA still dominate JWT and public TLS layers until your entire verifier chain supports modern curves. Start by inventorying where static keys live today.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: