toolhq.io

All posts
7 min readby Jameel Haider

ECDSA vs RSA certificates: which key type to use, and why

When you generate a certificate signing request you pick a key type, and most people pick RSA 2048 because that is what the tutorial said. It is a reasonable default. It is rarely the best one, and on a busy site the difference is measurable.

The short version

ECDSA with the P-256 curve gives you the security of a roughly 3072 bit RSA key, in a key that is a fraction of the size, with faster handshakes and lower CPU cost on the server. Client support has been effectively universal for years. For a public web server in 2026, ECDSA P-256 is the better default, and RSA 2048 is the compatibility fallback rather than the starting point.

The rest of this explains when that guidance does not hold.

Security strength is not key size

Comparing a 256 bit ECDSA key to a 2048 bit RSA key by the number alone is meaningless. The two use different mathematics and the numbers are not on the same scale. What matters is the work an attacker needs, expressed as a symmetric equivalent.

KeySymmetric equivalentComparable RSA
RSA 2048~112 bits
RSA 3072~128 bits
RSA 4096~140 bits
ECDSA P-256~128 bitsRSA 3072
ECDSA P-384~192 bitsRSA 7680

Two things follow. A P-256 key is stronger than the RSA 2048 key most sites run. And RSA 4096, which people reach for when they want more margin, buys surprisingly little over 3072 while costing a great deal of computation. If you want more than 128 bit equivalent strength, P-384 gets you there far more cheaply than RSA ever will.

Where the performance difference lands

In a modern handshake the key exchange is ECDHE regardless of your certificate type. Your certificate key is used for one thing: the server signs the handshake transcript to prove it holds the private key. So the operation that matters is signing, on the server, once per full handshake.

That is exactly where the two diverge. RSA signing is expensive and gets dramatically worse as the key grows. ECDSA signing is cheap. Verification runs the other way, RSA verifies faster than ECDSA, but verification happens on the client, where one operation per connection is irrelevant.

The practical result is that a server under connection load spends noticeably less CPU on ECDSA than on RSA 2048, and very much less than on RSA 4096. On a server terminating a high volume of new TLS connections this is one of the cheapest capacity wins available.

Size helps too. An ECDSA signature is around 64 bytes against 256 for RSA 2048, and the certificate itself is smaller. Across a full chain that trims a few hundred bytes from every handshake, which matters most on the first round trip over a slow mobile link.

Client support

This used to be the whole argument and now it is close to a formality. Every current browser and operating system has supported ECDSA P-256 for over a decade. The clients that genuinely cannot handle it are Windows XP, Android below 4.0, and old embedded or industrial equipment with a frozen TLS stack.

If your traffic is ordinary web traffic, this list is empty in practice. If you serve API clients on long lived embedded hardware, payment terminals, set top boxes, medical or industrial devices, check before switching. Those environments are where RSA still earns its place.

Note that P-256 and P-384 are broadly supported, while P-521 is not, despite sounding stronger. Some stacks omit it. Use P-256, or P-384 when you have a specific reason.

Serving both

If you need to support ancient clients without giving up the benefits for everyone else, you can install both certificates on the same host. The server picks based on what the client advertises in its handshake: a modern client offering ECDSA signature algorithms gets the ECDSA certificate, and anything else falls back to RSA.

Both nginx and Apache support this by listing multiple certificate and key pairs on the same virtual host. The cost is real but bounded: two certificates to issue, renew and monitor, two chains that can independently expire, and a configuration that is easy to get subtly wrong.

For most sites it is not worth it. Do it when you have measured evidence of legacy clients in your logs, not on the assumption that they might exist. If you do run a dual setup, monitor both certificates rather than whichever one your browser happens to receive, since an expiry on the fallback will only break the clients least able to tell you about it.

Making the switch

The key type is fixed at CSR time, so switching means generating a new key and a new request. With OpenSSL:

# ECDSA P-256
openssl ecparam -name prime256v1 -genkey -noout -out ecdsa.key
openssl req -new -key ecdsa.key -out ecdsa.csr

Or generate the key and request in the browser with the CSR generator, which lets you choose the curve and never transmits the private key.

Let's Encrypt issues ECDSA certificates for P-256 and P-384, so switching costs nothing at the CA. Most commercial CAs do too, though a few still charge differently or require a specific product, which is worth checking before you regenerate anything.

A detail that catches people out: your certificate key type and the CA's signing key type are independent. An ECDSA leaf can be signed by an RSA intermediate, which is common and completely fine. What you get is an ECDSA certificate in an RSA chain, and the performance benefit applies to your server's signing operation either way.

Checking what you actually have

Certificates do not advertise their key type in the browser padlock, so it is easy to assume you switched when a deployment quietly reverted. Paste the certificate into the SSL decoder to see the public key algorithm, curve or modulus size, and signature algorithm in plain terms, or check the live endpoint with the SSL checker to confirm what the server is genuinely presenting to clients.

If the deployed key type does not match what you generated, the usual cause is a web server still pointing at the previous certificate path, or a load balancer terminating TLS with its own configuration ahead of the origin.

Related reading: RSA key formats covers the encodings you will meet when converting keys, and the TLS handshake explained shows where the signing step fits.