Modernization

How weak keys led eMudhra to quit public TLS

A technical account of eMudhra's weak certificate authority keys, what Chrome, Mozilla and others decided, and code to check your own setup.

Cover illustration for How weak keys led eMudhra to quit public TLS
Cover illustration for How weak keys led eMudhra to quit public TLS

On 17 October 2026 a researcher showed that the private keys behind eight eMudhra certificate authority certificates were weak enough to work out in an instant. Browsers blocked the certificates within hours, and five days later eMudhra said it will leave the global SSL/TLS business. This is a technical account of what went wrong, what each party decided, what is still open, and how to check your own systems. One date matters: Chrome’s removal of the root that signed the certificates is expected to reach all devices on 27 October.

What happened, in order

Times are UTC. They come from the posts by Chrome, Mozilla and Cloudflare, Mozilla’s bug tracker and eMudhra’s statements.

Date What happened
30 Apr 2025 24 intermediate keys are generated in one ceremony. Eight (six TLS, two code-signing) turn out to be weak.
17 Oct 2026 A researcher reports it. Chrome blocks the TLS intermediates by 19:45 and Mozilla by 22:59.
18 Oct 2026 eMudhra revokes all eight.
19 Oct 2026 Apple blocks them, and Sectigo revokes its cross-signed copies.
20 Oct 2026 Microsoft blocks them. Mozilla and Chrome decide to remove the root that signed them.
22 Oct 2026 eMudhra says it will leave global SSL/TLS.
27 Oct 2026 Chrome’s root removal is expected to reach all devices.

Apple’s and Microsoft’s blocks are reported by iTnews and Help Net Security. The root is called emSign ECC Root CA - G3.

How the keys were weak

A P-384 private key is a secret number picked at random from a range of more than 100 digits. The public key is computed from it, and the public key sits in the certificate for anyone to read. Mozilla’s analysis found that all eight affected keys used integers less than 256. They were effectively zero apart from the last byte.

That makes recovery a search over 255 candidates: compute the public key for each small number and compare it with the certificate. This check does exactly that, and returns True if a certificate’s key is one of them:

from cryptography import x509
from cryptography.hazmat.primitives.asymmetric import ec


def has_tiny_ec_key(cert: x509.Certificate, limit: int = 256) -> bool:
    pub = cert.public_key()
    if not isinstance(pub, ec.EllipticCurvePublicKey):
        return False
    want = pub.public_numbers()
    for d in range(1, limit):
        got = ec.derive_private_key(d, pub.curve).public_key().public_numbers()
        if (got.x, got.y) == (want.x, want.y):
            return True
    return False

It needs pip install cryptography. We tested it on a certificate built from private key 4 (it returns True) and on a freshly generated key (it returns False). We also ran it on the eight revoked certificates from the public CCADB list of revoked intermediates. All eight were flagged, and so were the eight copies Sectigo cross-signed with the same keys. Four certificates from eMudhra’s G3A series, whose keys Mozilla could not recover, came out clean. Use it only on certificates you own or manage. A hit means the private key is effectively public. A result of False does not prove a key is strong: the check only finds keys below 256, and it skips keys that are not elliptic-curve keys. Help Net Security reports that a researcher recovered keys of 4, 56 and 115 from the public certificates in under a second, and Cloudflare’s post states the consequence: an attacker can create a forged certificate for any domain.

How the mistake happened

eMudhra’s account, which it says is not yet a confirmed root cause:

  • The ceremony included an approved deviation, to test a wrap and unwrap step.
  • A flaw in the code created a second, weaker pair of keys inside the hardware.
  • The weaker pair was used by mistake, because the key labels were similar.

It says the flaw was in one step of the procedure, not in the hardware security modules, and that there were human errors in more than one step. Mozilla found the problem only in the B and C series of P-384 keys. It could not recover the A-series keys and had not yet examined the RSA keys. Two earlier signals are worth knowing. According to eMudhra, the hierarchy passed two audit cycles. And Mozilla’s bug tracker links an earlier report about invalid signatures on the revocation lists of the same intermediates, with an Internet Archive snapshot showing failures from 23 May, before the date eMudhra gave.

What each party decided

  • Chrome: blocked the intermediates by public key hash at 19:45 UTC on 17 October, using a CRLSet (Chrome’s block list, which updates without a browser update). It removes the G3 root from its store, and asked Certificate Transparency logs (public logs where authorities record the certificates they issue) to reject certificates chaining to them. It is investigating whether eMudhra’s remaining certificate authorities should stay.
  • Mozilla: blocked them in under three hours through OneCRL (Firefox’s list of revoked intermediates, pushed without a browser update), shipped Firefox updates, and removes the G3 root in NSS 3.131.1 (Mozilla’s security library and list of trusted roots, which other software also uses). Its decision was an emergency removal of trust in G3, and “at this time” it is not removing trust in eMudhra’s G1 root.
  • Apple and Microsoft: blocked the certificates, on 19 and 20 October.
  • Sectigo: revoked the cross-signed copies of the eight intermediates.
  • Cloudflare: patched its services before the public disclosure and released client updates on 20 October.
  • eMudhra: revoked all eight on 18 October, stopped issuing under G3, and is moving about 30,000 certificates, about 97% of them issued through ACME, the automatic issuance protocol. It promised a full root-cause report and, in its press release, said it will leave global SSL/TLS. It cites a 1% revenue share, rising compliance cost, free certificates from large entities, and scrutiny out of proportion to the business. Revocation services keep running until every issued certificate has expired or been replaced, and Sectigo-issued certificates are on offer.
  • Indian government: Business Today reports that MeitY formed a special team and called the impact on Indian sites very limited, and that CERT-In issued an advisory.

What the industry is still asking

Chrome put twelve questions to eMudhra on 21 October in the bug tracker. The core ones:

  • When did it first know that several key pairs with similar labels existed?
  • Why were the revocation lists re-signed with the second key in June 2025, instead of halting operations and auditing?
  • Were Sectigo or any root program told then that the keys were not the intended ones?
  • How many certificates are affected and migrated per authority, before the 27 October removal?

Other participants asked how hardware-generated keys could be this small, and who approved the deviation. Some answers may come in eMudhra’s promised report.

Check your own setup

Cloudflare’s guidance is that certificate checking may sit in a library, a runtime, the operating system or a custom trust setup, so a browser test does not prove a background service is protected. It also warns against switching off certificate checks to clear errors, because that removes the protection the fixes restore. Two quick checks you can run today. First, see which chain a server presents, and look for emSign in the output:

echo | openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null \
  | sed -n '/BEGIN CERT/,/END CERT/p' \
  | openssl crl2pkcs7 -nocrl -certfile /dev/stdin \
  | openssl pkcs7 -print_certs -noout | grep -E 'subject|issuer'

Second, see whether a trust bundle still contains the G3 root. This uses Python’s certifi bundle (pip install cryptography certifi) and prints nothing if the root is gone:

import certifi
from cryptography import x509

with open(certifi.where(), "rb") as f:
    for cert in x509.load_pem_x509_certificates(f.read()):
        name = cert.subject.rfc4514_string()
        if "emSign ECC Root CA - G3" in name:
            print("still trusted:", name)

In our test, certifi 2026.10.23 no longer lists the G3 root but still lists emSign Root CA - G1. If you use eMudhra certificates, check whether they chain to G3 and replace them before 27 October. eMudhra says customers can ask for Sectigo-issued replacements through its support channels. For help with the inventory, a technical and security audit covers it, and the handover checklist shows how to map outside services.

Know who issues every certificate you depend on, and check the software that trusts them, not only the browser. Chrome’s removal of the G3 root on 27 October is the first deadline to check that list against.

Sources

Frequently asked questions

What is a certificate authority?

An organization that browsers and operating systems trust to vouch that a website's certificate belongs to its owner. If a certificate authority's signing keys are weak, anyone can forge certificates that browsers accept.

How weak were the keys?

Mozilla found that the eight keys all used integers less than 256. A proper P-384 key is a random number of more than 100 digits, so these could be found by trying at most 255 candidates.

Was anyone attacked using the weak keys?

Chrome says no certificates chaining to the affected authorities were logged to Certificate Transparency (public logs where authorities record every certificate they issue) before it blocked them, and Cloudflare found no active exploitation on its services. Nobody has said whether anyone used the keys elsewhere in the 17 months before they were reported.

Do I need to act if I don't use eMudhra?

Browsers are protected without an update. Other software may not be, because certificate checking can sit in a library, a runtime, the operating system or a custom trust setup, as Cloudflare points out. Check that your own services do not trust the eMudhra G3 root.

Why did eMudhra leave public TLS?

Its board decided on 22 October 2026 to withdraw from the global SSL/TLS certificate business. Its press release says the business is about 1% of global revenue, compliance and data sovereignty requirements made it costly, large entities issue certificates free, and scrutiny of the incident was out of proportion to the business's role in the company.

How do I make it easier to switch certificate authorities?

Keep an inventory of every certificate and its issuer, automate issuance and renewal with ACME (the standard protocol for requesting and renewing certificates automatically) where you can, and keep a second certificate authority ready for critical domains. Maximum certificate lifetimes are scheduled to fall from 398 days to 47 days between March 2026 and March 2029.

  • certificate authority
  • TLS certificates
  • eMudhra
  • vendor risk
  • certificate management

Want to talk this through?

Tell us what you're building, fixing or scaling and a senior engineer will reply with a clear next step.

Request a consultation
Let's build what's next

Have a complex technology problem? Let's talk.

Tell us what you're building, fixing or trying to scale. We'll help you understand the next step.