Back to Blog

RFC 10015 Just Retired RSA and DHE in TLS 1.2. ECDHE Is What's Left.

RFC 10015 stamps MUST NOT on RSA and finite-field DH key exchange in TLS 1.2, including ephemeral DHE. Here's what your servers still speak and how to check.

CertGuard TeamSSL Security Experts10 min read
A long aisle between two rows of tall metal equipment racks in an industrial server hall, lit from a distant window under an exposed steel-truss ceiling

The RFC that quietly voided part of your cipher list

Nobody emails you about a TLS working group document. They should have, this time. In July 2026 the IETF published RFC 10015, "Deprecating Obsolete Key Exchange Methods in TLS 1.2 and DTLS 1.2," on the Standards Track. Your servers still speak 1.2. Everyone's do. And a stack of cipher suites you have been running since roughly 2015 just got a MUST NOT stamped on them.

This is not a compliance nag you can defer to next quarter. It is the IETF saying, on the record, that a whole family of key exchanges is no longer acceptable for the protocol version that still carries a big share of real traffic. Worth ten minutes before an auditor spends ten minutes on it for you.

What the document actually deprecates

Three verdicts, and they are not all the same strength.

RSA key exchange is dead. In the RFC's words, clients MUST NOT offer and servers MUST NOT select RSA cipher suites in (D)TLS 1.2 connections. That is every TLS_RSA_WITH_* suite where RSA does the key transport.

Finite-field Diffie-Hellman is dead too, and this is the part people miss. Clients MUST NOT offer and servers MUST NOT select FFDHE cipher suites in (D)TLS 1.2 connections. Not just the static variants. The ephemeral ones too. More on that in a second, because it surprises people.

Static elliptic-curve DH gets the softer treatment: SHOULD NOT rather than MUST NOT. The four fixed-DH certificate types (rsa_fixed_dh, dss_fixed_dh, rsa_fixed_ecdh, ecdsa_fixed_ecdh) are deprecated outright, though almost nobody was issuing those anyway.

Add it up and you are looking at roughly two hundred cipher suites across the RSA, DH, DHE, and ECDH families. The document updates seventeen earlier RFCs in the process, including RFC 9325, which is BCP 195, the actual best-practice recommendations for using TLS that most hardening guides crib from. When BCP 195 moves, the goalposts for "secure config" move with it.

Yes, ephemeral DHE is on the list

Here is where a lot of engineers do a double take. Ephemeral means forward secrecy, and forward secrecy is the thing we spent a decade telling everyone to turn on. So why is DHE-RSA-AES256-GCM-SHA384 suddenly forbidden?

Because forward secrecy is necessary, not sufficient. Finite-field Diffie-Hellman has two problems ephemeral keys do not fix. Weak and shared groups are the big one. Logjam showed that a handful of large precomputations against common 1024-bit groups let an attacker decrypt a big fraction of FFDHE traffic after the fact. The RFC says it plainly: "just a handful of very large computations allow an attacker to cheaply decrypt a relatively large fraction of FFDHE traffic." The second is Raccoon, a timing side channel that leaks when secrets are not fully ephemeral. Neither touches elliptic-curve DH.

So the survivor is ECDHE. Ephemeral elliptic-curve Diffie-Hellman keeps forward secrecy without the weak-group and side-channel baggage. In practice that means your TLS 1.2 handshakes should all be doing ECDHE now, full stop. If any of them are still landing on plain RSA or DHE, that is the gap to close.

ECDHE-RSA is fine. TLS_RSA is not.

This trips people up every single time, so let me be blunt about it. There are two completely different jobs happening in a cipher suite name, and RSA can appear in either.

In TLS_RSA_WITH_AES_128_GCM_SHA256, RSA is doing the key exchange. The client encrypts the premaster secret to the server's RSA public key. That is the thing RFC 10015 kills, because it has zero forward secrecy by construction and Bleichenbacher-style attacks keep coming back every few years (ROBOT was just the 2017 reprise).

In ECDHE-RSA-AES128-GCM-SHA256, the ECDHE does the key exchange and RSA only signs the handshake to prove the server owns the certificate. That RSA is authentication, not key transport. It is completely fine. You do not need to rip RSA certificates out of production. You need to stop using RSA to exchange keys.

So an RSA certificate paired with ECDHE suites is exactly where you want to be. ECDSA certificates with ECDHE-ECDSA-* suites work the same way and are lighter on the wire if you are already dual-certing.

Fixing your server config

For nginx, the safe TLS 1.2 posture is ECDHE-only, and you let TLS 1.3 manage its own suites (you do not configure those, they are hardcoded in the spec).

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_prefer_server_ciphers off;

Notice there is not a single DHE or bare RSA suite in that list. If you copied a cipher string off a blog in 2018, go check it now, because half of those old "Intermediate" strings still carry DHE-RSA fallbacks.

You can ask OpenSSL what a given cipher string actually expands to before you deploy it. This is the fastest way to catch a forbidden suite hiding in a preset:

# Expand your intended cipher string and eyeball the key exchange column
openssl ciphers -v 'ECDHE:!aNULL' | awk '{print $1, $3}'

# Anything printing "Kx=RSA" or "Kx=DH" is now deprecated for 1.2
openssl ciphers -v 'DEFAULT' | grep -E 'Kx=RSA|Kx=DH ' || echo "clean"

The Kx= field is the key exchange. Kx=ECDH is what you want to see across the board.

Find out what you're actually negotiating

Config is one thing. What a server does on the wire under a real client is another, especially behind a load balancer or CDN that terminates TLS with its own settings. Test the live endpoint.

# Ask the server directly: will it still do an RSA key exchange?
openssl s_client -connect example.com:443 -tls1_2 -cipher 'aRSA:kRSA' </dev/null 2>/dev/null | grep -E 'Cipher|New,'

# And will it still do finite-field DHE?
openssl s_client -connect example.com:443 -tls1_2 -cipher 'DHE' </dev/null 2>/dev/null | grep -E 'Cipher|New,'

If either handshake succeeds, you are still offering something the RFC now forbids. A clean server answers those two with a handshake failure. For the full picture across every protocol version, nmap enumerates the lot and grades it:

nmap --script ssl-enum-ciphers -p 443 example.com

Look for any suite starting TLS_RSA_ or TLS_DHE_ under the TLSv1.2 section. Those are your action items. If you already run testssl.sh, its per-protocol cipher output tells you the same story, and its output is easy to diff in a pipeline so you catch a config regression the day it ships. That kind of drift detection is the whole reason to wire cert and TLS checks into CI, which the DevOps SSL monitoring pipeline post walks through end to end.

The clients that will actually break

Tightening ciphers is where nervous teams freeze, because the fear is always the same: what breaks. Honest answer, mostly ancient things. Java 7 and unpatched Java 8 clients that never learned ECDHE well. Old embedded firmware and IoT gear shipped with an RSA-only TLS stack. A few payment terminals and B2B partners still pinned to TLS_RSA suites because someone certified an integration in 2014 and never touched it.

The move here is to look before you leap. Turn on cipher and protocol logging, watch for a week or two, and see who is actually landing on the doomed suites before you pull them. In nginx that is two variables in your log format:

log_format tls_audit '$remote_addr $ssl_protocol $ssl_cipher "$http_user_agent"';
access_log /var/log/nginx/tls_audit.log tls_audit;

Grep that for DHE or for cipher names ending in the old RSA-kx pattern. If the count is zero, remove the suites and move on with your afternoon. If it is not zero, now you have a named list of clients to migrate instead of a vague dread. When the handshakes do start failing during the cutover, the TLS handshake failure debugging post covers reading the alerts so you know whether it is a cipher mismatch or something else wearing the same error.

TLS 1.3 already did this for you

The tidy part of this story is that TLS 1.3 solved the problem before the RFC formalized it for 1.2. There is no RSA key exchange in 1.3. There is no static DH. Forward secrecy is mandatory, so every 1.3 handshake is already doing an ephemeral exchange. RFC 10015 even carves out that FFDHE in TLS 1.3 is fine, because the 1.3 handshake does not carry the weaknesses that sank it in 1.2. The named 1.3 groups are strong and the negotiation is authenticated.

Which means the real long-term fix is not babysitting a 1.2 cipher string forever. It is getting as much traffic as you can onto 1.3 and treating 1.2 as the shrinking legacy tail it is. If you are already thinking that far ahead, the next cliff is the key exchange itself going post-quantum, and your certificates lagging behind it, which is a whole separate headache covered in your key exchange went post-quantum, your certificates didn't.

For now, do the boring thing. Pull RSA and DHE out of your 1.2 config, confirm ECDHE is carrying every handshake, log who breaks, and migrate them. An afternoon of work that keeps you on the right side of a spec your auditors will be quoting by next year.

Frequently asked questions

Does RFC 10015 mean I have to stop using RSA certificates? No. The RFC deprecates RSA as a key exchange method, which is the TLS_RSA_WITH_* suites where the client encrypts a secret to your RSA public key. An RSA certificate used with ECDHE suites like ECDHE-RSA-AES128-GCM-SHA256 is still completely fine, because there the RSA key only signs the handshake for authentication and never does key transport.

Why is ephemeral DHE deprecated when it provides forward secrecy? Forward secrecy is not the only concern. Finite-field DH is vulnerable to the Logjam class of attacks against weak and widely shared groups, where a few precomputations let an attacker decrypt a large slice of traffic, and to the Raccoon timing side channel when secrets are not fully ephemeral. Ephemeral keys do not fix either problem, so RFC 10015 says MUST NOT for FFDHE in TLS 1.2 while leaving ephemeral ECDHE as the recommended path.

Is TLS 1.3 affected by this deprecation? No, and that is deliberate. TLS 1.3 already dropped RSA key exchange and static DH and makes forward secrecy mandatory, so it never had the problem. The RFC explicitly allows FFDHE in TLS 1.3 because the 1.3 handshake avoids the weaknesses that made finite-field DH unsafe in 1.2, which is one more reason to move traffic onto 1.3.

How do I check whether my servers still offer the deprecated suites? Test the live endpoint rather than trusting the config file. Run openssl s_client -connect host:443 -tls1_2 -cipher 'DHE' and again with 'kRSA', and if either handshake succeeds you are still offering a forbidden suite. For a full sweep use nmap --script ssl-enum-ciphers -p 443 host and look for any TLS_RSA_ or TLS_DHE_ entry under the TLSv1.2 section.

Will removing these cipher suites break older clients? It can, but usually only genuinely old ones: unpatched Java 7 and 8, legacy embedded firmware, and some payment or B2B integrations pinned to RSA suites years ago. Turn on cipher logging first, watch which clients land on the deprecated suites over a week or two, and you will get a concrete migration list instead of guessing before you remove anything.

Related posts

Never miss an expiring certificate again

CertGuard watches your SSL certificates and domains, and alerts you long before anything expires. Free for your first five domains.

Start Free