ECDSA (Elliptic Curve Digital Signature Algorithm)
ECDSA is the elliptic-curve digital signature algorithm standardised in FIPS 186-5, used to authenticate TLS certificates and handshakes. It only signs and verifies: it never encrypts or exchanges keys. P-256 gives 128-bit security with far smaller keys than RSA-3072, and signs far more cheaply.
Also known as Elliptic Curve Digital Signature Algorithm.
Full Explanation
ECDSA (Elliptic Curve Digital Signature Algorithm) is the elliptic-curve digital signature scheme standardised in FIPS 186-5. It authenticates the certificates and handshakes behind HTTPS on a TLS connection. Signing uses a private key and a hash of the message. Verification uses only the matching public key. So anyone can check a signature, and only the key holder can produce one.
ECDSA is not encryption. It is not key exchange either. TLS 1.3 removed static RSA and Diffie-Hellman key exchange. So every public-key key exchange is now ephemeral, normally ECDHE. In TLS 1.3, a certificate key is used for signing only (RFC 9846, section 1.3). FIPS 186-5 is blunter still: “ECDSA is the elliptic curve analog of DSA. ECDSA keys shall not be used for any other purpose (e.g., key establishment)” (FIPS 186-5, section 6). The curve is shared. P-256 is approved for both ECDSA and EC key establishment (NIST SP 800-186, Table 2). But the key must not be shared. ECDSA is also not EdDSA. Ed25519 and Ed448 are a different signature scheme on a different curve family. They have their own TLS code points (RFC 9846, section 4.3.3). One note on currency: check this before following any older reference. RFC 9846 (July 2026) obsoletes both RFC 8446 and RFC 8422. So the classic citations for ECDSA in TLS now point at superseded documents.
The helicopter view for CDN work: at P-256, ECDSA reaches 128-bit security with a 256-bit key. RSA needs 3072 bits for the same security level (NIST SP 800-57 Part 1 Rev. 5, Table 2). So keys, signatures and whole certificate chains shrink. The single private-key operation each handshake needs is also far cheaper than the RSA equivalent. Verification, which the client does, is not faster than RSA. The saving is on the signing side. That is exactly the side a CDN edge pays for.
How it works
- Hash the message. The signer computes H = Hash(M) with an approved hash function or extendable-output function. Then it derives an integer e from it (FIPS 186-5, section 6.4.1).
- Sign with a per-message secret. Generate a per-message secret number k with 0 < k < n. Compute the curve point R = [k]G. Set r to the x-coordinate of R, reduced modulo n. Then compute s = k^-1 (e + r·d) mod n. Here d is the private key, and k^-1 is the inverse of k modulo n. The output is a pair of integers (r, s), each in the interval [1, n-1] (FIPS 186-5, section 6.4.1).
- k must be fresh every time. “A new secret random number k, 0 < k < n, shall be generated prior to the generation of each digital signature for use during the signature generation process.” FIPS 186-5 permits k to be produced in two ways. It can be random (section 6.3.1). Or it can be deterministic, computed from the message and the private key (section 6.3.2, deterministic ECDSA) (FIPS 186-5, section 6.3).
- Verify from the public key alone. The verifier recomputes e. Then it computes u = e·s^-1 mod n and v = r·s^-1 mod n. It computes R1 = [u]G + [v]Q using the public key Q, and accepts the signature only if r equals the x-coordinate of R1 modulo n (FIPS 186-5, section 6.4.2). No private key and no shared secret takes part in verification.
- On the wire. “The signature is represented as a DER-encoded [X690] ECDSA-Sig-Value structure”. Each TLS 1.3 signature scheme binds one curve to one hash: ecdsa_secp256r1_sha256 (0x0403), ecdsa_secp384r1_sha384 (0x0503) and ecdsa_secp521r1_sha512 (0x0603) (RFC 9846, section 4.3.3). Absent an application profile standard specifying otherwise, “a TLS-compliant application MUST support digital signatures with … ecdsa_secp256r1_sha256” (RFC 9846, section 9.1). This is why P-256 with SHA-256 is the safe default.
- Where it appears in the handshake. Two distinct kinds of ECDSA signature are in play. The CA signed each certificate in the chain. The server signs the handshake itself. In TLS 1.3, the CertificateVerify message carries a signature over the transcript hash. It does not carry a signature over the key-exchange parameters, as TLS 1.2's ECDHE_ECDSA does (RFC 9846, section 4.5.2).
Why it matters for a CDN
Size. Judge an ECDSA key by its curve, not by comparing its bit length with an RSA key's. NIST puts the approximate security strength of P-256, P-384 and P-521 at 128, 192 and 256 bits respectively (NIST SP 800-186, Table 1). Its equivalence table puts 128-bit security at an elliptic-curve key of 256 to 383 bits against an RSA modulus of 3072 bits. It puts 192-bit security at 384 to 511 bits of curve against RSA-7680 (SP 800-57 Part 1 Rev. 5, Table 2). A P-256 public key is an uncompressed point: a one-octet form byte followed by X and Y: “for P-256, this means that each of X and Y use 32 octets” (RFC 9846, section 4.3.8.2). An X.509 certificate carries the same uncompressed point (RFC 5480, section 2.2). So that is 65 octets of public key against 256 octets for an RSA-2048 modulus. Every certificate in the chain carries both a public key and a signature (RFC 9846, section 4.5.1). So the effect compounds: “smaller public keys mean smaller certificates and less data to pass around to establish a TLS connection” (Cloudflare, 2014). Let's Encrypt calls the ECDSA certificate simply “much smaller” (Let’s Encrypt integration guide). Treat headline ratios with care. Cloudflare's often-quoted 12x figure is P-256 against RSA-3072. The same page immediately qualifies it: “most RSA keys are not 3072 bits, so a 12x amplification factor may not be the most realistic figure” (Cloudflare, “ECDSA: The missing piece of DNSSEC”). Real web certificates mostly use RSA-2048, an 8x key-size ratio. RSA-2048 only reaches the 112-bit security level. So that comparison is against a weaker key, not an equal one.
Size. NIST's equivalence table puts 128-bit security at an elliptic-curve key of 256 to 383 bits against an RSA modulus of 3072 bits. It puts 192-bit security at 384 to 511 bits of curve against RSA-7680 (SP 800-57 Part 1 Rev. 5, Table 2). A P-256 public key is an uncompressed point: a one-octet form byte followed by X and Y: “for P-256, this means that each of X and Y use 32 octets” (RFC 9846, section 4.3.8.2). The same uncompressed point is what an X.509 certificate carries (RFC 5480, section 2.2). So that is 65 octets against 256 octets for an RSA-2048 modulus. Every certificate in the chain carries both a public key and a signature (RFC 9846, section 4.5.1). So the effect compounds. Cloudflare's framing is that “smaller public keys mean smaller certificates and less data to pass around to establish a TLS connection” (Cloudflare, 2014). Let's Encrypt calls the ECDSA certificate simply “much smaller” (Let’s Encrypt integration guide). Be careful with the headline ratios. Cloudflare's own 12x key-size figure is against RSA-3072. The same page adds that “most RSA keys are not 3072 bits, so a 12x amplification factor may not be the most realistic figure”. Typical web certificates use RSA-2048. So 8x is the honest comparison (Cloudflare, “ECDSA: The missing piece of DNSSEC”).
Signing cost. This is the bigger CDN win, because signing is what the edge does. “The private key is only used once in each handshake” (Cloudflare Keyless SSL). That is one CertificateVerify signature per full handshake, multiplied by every connection an edge server terminates. Cloudflare measures ECDSA signing as “10x less computationally expensive … than a comparable RSA signature” in its DNSSEC signing work (Cloudflare). Its published OpenSSL 1.0.2-beta benchmark from 2014 recorded “256 bit ecdsa (nistp256) 9516.8 / rsa 2048 bits 1001.8” signatures per second, “reduc[ing] the cost of the private key operation by a factor of 9.5x” (Cloudflare, 2014). Those are 2014 numbers on 2014 hardware and software. Treat them as the shape of the gap, not as today's throughput. Cheaper signing is also why a CDN can move that operation off-box at all: Keyless SSL exists precisely because there is only one private-key operation per handshake to relocate.
What CDNs do
- Cloudflare: “Cloudflare can issue both RSA and ECDSA certificates”. For Universal SSL, “Universal certificates on free zones only receive an ECDSA certificate. Paid zones receive an RSA and ECDSA certificate” (Cloudflare SSL/TLS FAQ). That policy is old: “In 2014, Cloudflare launched elliptic curve digital signature algorithm (ECDSA) support for Cloudflare-issued certificates and made the decision to issue ECDSA-only certificates to free customers” (Cloudflare, 2024).
- Fastly supports “key sizes of 256 bits and 384 bits for ECDSA public key encryption”. It states that “for performance reasons and to help mitigate your security costs, we strongly recommend using an ECDSA certificate” (Fastly TLS service options). On Dedicated IP addresses, and “for self-managed certificates only”, you can nominate default certificates of both types. When no SNI match is found, “Fastly will first check if the client supports ECDSA. If it does, we will send the fallback ECDSA certificate. If there is no SNI match and the client does not support ECDSA, we send the RSA fallback certificate” (Fastly Dedicated IP addresses).
- Akamai: “Akamai now supports both ECDSA and RSA keys for all new and existing third-party certificates provisioned in Certificate Provisioning System (CPS)”. Dual-stack support has been available for Akamai-managed OV and EV certificates since 2017. When both key types are provisioned, the edge network “prefers ECDSA due to its superior performance over RSA” with no extra configuration (Akamai CPS release notes, July 2022).
- Amazon CloudFront: “CloudFront supports RSA and ECDSA public–private key pairs” for HTTPS to both viewers and origins. For ECDSA it “supports 256-bit and 384-bit keys”, and “to use an ECDSA certificate in ACM to require HTTPS between viewers and CloudFront, use the prime256v1 or secp384r1 elliptic curve” (AWS CloudFront certificate requirements).
- CAs and ACME clients: “Let's Encrypt accepts RSA keys that are 2048, 3072, or 4096 bits in length and P-256 or P-384 ECDSA keys”. Its recommendation is “to serve a dual-cert config, offering an RSA certificate by default, and a (much smaller) ECDSA certificate to those clients that indicate support” (Let’s Encrypt integration guide). Key type is no longer something you have to ask for: “as of version 2.0.0, Certbot defaults to ECDSA secp256r1 (P-256) certificate private keys for all new certificates”. Use --key-type and --elliptic-curve to override (Certbot user guide).
Watch out for
- A reused or predictable k leaks the private key. This is ECDSA's signature failure mode, not a theoretical one: “in 2010, a flaw in the way random numbers were used in ECDSA on Sony's Playstation 3 resulted in a private key being leaked”, and “some Android devices were found to be incorrectly generating random values, resulting in a massive theft of Bitcoins” (Cloudflare, 2014). There are two mitigations, and both are compatible with every existing verifier. One is a properly seeded CSPRNG, which TLS requires anyway (RFC 9846, appendix C.1). The other is deterministic ECDSA, standardised as RFC 6979 and now approved in FIPS 186-5, section 6.3.2.
- Verification is slower than RSA, not faster. The signing win does not extend to the verifying side. “While ECDSA signature creation is faster than RSA, signature validation is actually much slower”. This was measured by van Rijswijk-Deij et al.: “even with the ECDSA optimizations that we contributed to OpenSSL, ECDSA is still 6.6 times slower than 1024-bit RSA” (Cloudflare). That measurement is from DNSSEC resolver validation against 1024-bit zone-signing keys. So do not carry the 6.6 figure over to TLS verification unchanged. But do carry over the direction: clients pay more to verify ECDSA, edges pay much less to sign it.
- The chain only shrinks if the intermediates are ECDSA too. An ECDSA leaf issued under an RSA intermediate keeps the intermediate's RSA key and signature on the wire. Let's Encrypt now separates the hierarchies: “subscriber certificates containing an ECDSA public key will be issued from one of the ECDSA intermediates”. It uses ECDSA P-384 intermediates and roots, though the default chain still cross-signs up to the RSA-4096 ISRG Root X1 (Let’s Encrypt chain of trust). The trust anchor itself is normally not transmitted: “a certificate that specifies a trust anchor MAY be omitted from the chain” (RFC 9846, section 4.5.1). So measure the chain you actually serve, not the one you drew.
- ECDSA cannot decrypt and cannot carry key exchange. It signs, and that is all. Forward secrecy comes from the ephemeral key exchange sitting beside it, not from the certificate. TLS 1.3 removed static RSA and Diffie-Hellman entirely. So “all public-key based key exchange mechanisms now provide forward secrecy” (RFC 9846, section 1.3).
- Clients that cannot do ECDSA fail the handshake outright. Cloudflare's 2014 rollout note is still the plain statement of the failure mode: “if the HTTPS version site does not load, your browser probably does not support ECDSA” (Cloudflare, 2014). These sources do not establish how large that population still is in 2026. So measure it on your own traffic rather than assuming. Keeping an RSA certificate alongside is the cheap insurance. It is what Let's Encrypt, Akamai and Cloudflare's paid tiers all do.
- There is a clock on ECDSA. Elliptic-curve signatures are not quantum-resistant. NIST's draft transition guidance places ECDSA at 128-bit strength and above in the “disallowed after 2035” column. The 112-bit level is deprecated after 2030 (NIST IR 8547, initial public draft, November 2024, Table 3). That is a draft, not a final rule. But certificate lifetimes and hardware refresh cycles are long enough that it belongs in planning now.
Best practice
- Default to P-256. ecdsa_secp256r1_sha256 is the mandatory-to-implement signature scheme (RFC 9846, section 9.1). Certbot has issued P-256 keys by default since 2.0.0 (Certbot user guide). Move to P-384 only when a compliance profile actually requires 192-bit security. Size by curve rather than by bit length: P-256, P-384 and P-521 sit at roughly 128, 192 and 256 bits (SP 800-186, Table 1).
- Serve both key types and let the handshake choose. Let's Encrypt recommends “a dual-cert config, offering an RSA certificate by default, and a (much smaller) ECDSA certificate to those clients that indicate support” (Let’s Encrypt integration guide). Akamai's edge “prefers ECDSA due to its superior performance over RSA” when both are provisioned (Akamai CPS). Fastly picks ECDSA first for capable clients on its fallback path (Fastly). On your own origin or a self-managed edge, nginx has done this since 1.11.0: “this directive can be specified multiple times to load certificates of different types, for example, RSA and ECDSA” (nginx ssl_certificate).
- Fix the nonce source before anything else. Use a platform CSPRNG or deterministic ECDSA. Never let k repeat across signatures (FIPS 186-5, sections 6.3 and 6.4.1; RFC 6979).
- Keep the private key where you want it. Only one private-key operation happens per handshake, so it can be relocated. Keyless SSL-style designs keep the key on your infrastructure while the edge runs the rest of the handshake (Cloudflare Keyless SSL).
- Verify what is actually served, per hostname. Certificate selection happens at the edge, not at the origin. So the origin's key type tells you nothing about what clients see. Check the chain the edge returns for the SNI name in question. Confirm the leaf really is id-ecPublicKey. Confirm the intermediates are ECDSA too, if you are counting on the size saving (Let’s Encrypt chain of trust).
Examples
# Generate ECDSA private key
openssl ecparam -genkey -name prime256v1 | \
openssl ec -out ecdsa_key.pem
# Generate CSR with ECDSA key
openssl req -new -key ecdsa_key.pem \
-out ecdsa.csr -sha256 \
-subj "/CN=example.com"
# Request ECDSA cert from Let's Encrypt
certbot certonly --standalone \
--key-type ecdsa --elliptic-curve secp256r1 \
-d example.com
# Check if a site uses ECDSA or RSA
openssl s_client -connect example.com:443 \
-servername example.com 2>/dev/null | \
openssl x509 -noout -text | grep 'Public Key Algorithm'
# Public Key Algorithm: id-ecPublicKey
# (versus rsaEncryption for RSA)
# Compare key sizes
openssl ec -in ecdsa_key.pem -text -noout 2>/dev/null | head -2
# Private-Key: (256 bit)
openssl rsa -in rsa_key.pem -text -noout 2>/dev/null | head -2
# Private-Key: (2048 bit)
# Nginx: serve ECDSA cert with RSA fallback
ssl_certificate /etc/ssl/ecdsa_cert.pem;
ssl_certificate_key /etc/ssl/ecdsa_key.pem;
ssl_certificate /etc/ssl/rsa_cert.pem;
ssl_certificate_key /etc/ssl/rsa_key.pem;
Frequently Asked Questions
ECDSA is the elliptic-curve digital signature algorithm standardised in FIPS 186-5, used to authenticate TLS certificates and handshakes. It only signs and verifies: it never encrypts or exchanges keys. P-256 gives 128-bit security with far smaller keys than RSA-3072, and signs far more cheaply.
# Generate ECDSA private key
openssl ecparam -genkey -name prime256v1 | \
openssl ec -out ecdsa_key.pem
# Generate CSR with ECDSA key
openssl req -new -key ecdsa_key.pem \
-out ecdsa.csr -sha256 \
-subj "/CN=example.com"
# Request ECDSA cert from Let's Encrypt
certbot certonly --standalone \
--key-type ecdsa --elliptic-curve secp256r1 \
-d example.com
# Check if a site uses ECDSA or RSA
openssl s_client -connect example.com:443 \
-servername example.com 2>/dev/null | \
openssl x509 -noout -text | grep 'Public Key Algorithm'
# Public Key Algorithm: id-ecPublicKey
# (versus rsaEncryption for RSA)
# Compare key sizes
openssl ec -in ecdsa_key.pem -text -noout 2>/dev/null | head -2
# Private-Key: (256 bit)
openssl rsa -in rsa_key.pem -text -noout 2>/dev/null | head -2
# Private-Key: (2048 bit)
# Nginx: serve ECDSA cert with RSA fallback
ssl_certificate /etc/ssl/ecdsa_cert.pem;
ssl_certificate_key /etc/ssl/ecdsa_key.pem;
ssl_certificate /etc/ssl/rsa_cert.pem;
ssl_certificate_key /etc/ssl/rsa_key.pem;
Yes. ECDSA (Elliptic Curve Digital Signature Algorithm) is also known as Elliptic Curve Digital Signature Algorithm. ECDSA is the elliptic-curve digital signature algorithm standardised in FIPS 186-5, used to authenticate TLS certificates and handshakes. It only signs and verifies: it never encrypts or exchanges keys. P-256 gives 128-bit security with far smaller keys than RSA-3072, and signs far more cheaply.
Related CDN concepts include:
- TLS (Transport Layer Security) (TLS) — TLS (Transport Layer Security) is the protocol that turns a plain byte stream into a …
- ACME (Automated Certificate Management) (ACME) — ACME (Automatic Certificate Management Environment) is the IETF protocol in RFC 8555 that automates issuing, …
- ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) (ECDHE) — ECDHE is TLS key agreement over an elliptic curve using a fresh, ephemeral key pair …