Eight intermediate certificate authority keys belonging to eMudhra, an Indian CA trusted by every major browser, are small whole numbers. One of them is 4. Anyone holding the public certificates can compute the private keys in under a second, and anyone holding the private keys can sign a certificate for any domain that a client trusting those intermediates will accept. A researcher known only as Wayne reported this to the browser root programs on Saturday, October 17. Chrome and Firefox blocked the keys that evening. Everything that is not a browser is still catching up.

Mozilla's post has the timeline. The report reached Mozilla at 20:06 UTC. By 22:59 UTC a OneCRL block had reached every Firefox install with default settings. Chrome's root program received the report at 18:05 UTC and had a CRLSet update out by 19:45 UTC, per Google's post. Neither block needed a browser update or a restart. Apple blocked the certificates on October 19 and Microsoft on October 20.

How a CA ends up with a key of 4

A P-384 private key is supposed to be a random integer drawn from about 2^384 possibilities. eMudhra's keys were integers under 256. Scott Helme recovered all eight on a laptop and reported it took less than a second. He found 4, 56 and 115 himself. Other researchers found 66, 155, 156, 230 and 237. Testing whether a public key corresponds to a tiny private key is a loop of a few hundred scalar multiplications. Milliseconds of work.

eMudhra's account, in an October 21 filing with the Bombay Stock Exchange, is that the eight intermediates came out of a key ceremony on April 30, 2025, run on FIPS 140-2 Level 3 HSMs. A flaw in a key wrap and unwrap step produced a second, weak set of keys alongside the strong ones, and the weak set is what went into the certificates submitted to the root stores. The Mozilla bug calls it a "flaw in the KGC script." The company says its root keys and infrastructure were untouched, that only one of the eight intermediates was ever deployed in production, and that none of them issued an end entity certificate.

I don't know how a key wrap step turns a 384-bit random number into 4. Nobody commenting publicly knows either. The HSM part of the story is plausible, since HSMs do what the script tells them. What bothers me is that these certificates sat in the Mozilla, Chrome, Apple and Microsoft root stores for 18 months, passed two annual audits, and nobody ran a check that costs under a second per certificate. Chrome says it has now scanned every other CA in its store and found no other instance of this failure. That scan should have been standing policy, not an incident response.

The browsers were fine. Your servers weren't.

Certificate Transparency saved the browser case. Chrome requires public certificates to be logged, and no TLS certificate chaining to the six TLS intermediates appeared in any CT log before the block. So nothing forged could have worked against Chrome, or against Android apps that enforce CT. Firefox had the block the same night and Safari within two days. Browser users were never exposed in any way that matters.

That leaves everything else. curl. Python requests through certifi. Go binaries. Node. The TLS client inside every monitoring agent, webhook sender, package manager and backup job you run. Most of these never check revocation at all. They trust whatever root bundle they were built or installed with, and that bundle contained emSign ECC Root CA - G3, the root above the bad intermediates. Until the bundle changes, a certificate signed with the number 4 is as good as a real one to those clients. And a forged certificate for an internal API hostname never needs to appear in a CT log to work against a Go service that doesn't check CT.

Dennis Jackson of Mozilla put up a status page tracking who has shipped a fix. As of this morning the patched list includes ca-certificates on Ubuntu, Debian, Fedora, Arch, Alpine and Gentoo, NSS 3.131.1, curl's bundle, Go 1.27.3 and 1.26.10, Python certifi 2026.10.19, pip, uv, Rust webpki-roots 1.0.10, Electron, Composer and Homebrew. Node.js, Bun and FreeBSD are pending. The curl built into macOS still accepts the chain because Apple has not updated its system cert.pem, and the page offers a manual workaround that it tells ordinary users not to run.

Go's handling is the one to study. The Go team learned of the problem on October 19 and shipped on October 20 on its urgent track, with release notes that cited "specific security concerns" about an unnamed CA. The fix hardcodes the eight key hashes into the x509 package and rejects any chain containing them, on Go's own verifier and on the macOS and Windows system verifier paths. There is no flag to turn it off. Filippo Valsorda said hardcoding was the only option because Linux root stores are too poorly maintained for revocation to reach applications in time. He's right. It also means every Go binary you run needs a rebuild, and anything on Go 1.25 or older gets nothing.

What to do this week

  1. Run the curl test from Jackson's page against each class of host you operate. A certificate error is the passing result.
  2. Update ca-certificates on every Linux box. Then do the container base images, because a patched host does nothing for a container carrying a six month old bundle.
  3. Rebuild Go services on 1.27.3 or 1.26.10. Rebuild Python images so they pick up the new certifi. Watch Node and Bun for releases.
  4. Replace anything chaining to emSign ECC Root CA - G3 before October 27. Chrome removes that root from its store that morning. Mozilla pulled it from NSS on October 20.
  5. Check client certificate configuration. One of the revoked TLS intermediates carried the Client Auth extended key usage, so a service that accepts client certs from every public CA was exposed a second way.

There are also Sectigo cross-signed copies of all eight intermediates under the AAA Certificate Services root. Chrome and Firefox stopped trusting that root for websites in April 2025, and Chrome's block matches on the public key anyway, so the cross-signs change nothing there. Apple still ships AAA Certificate Services in iOS 26 and macOS 26, and Microsoft trusts it. Homebrew's fix drops that root along with eMudhra's.

Eighteen months of trust for a key you could guess

eMudhra's global TLS business is about 1% of its revenue, by its own filing. Its shares fell 20% in Mumbai on October 21. Chrome has removed the ECC root and is reviewing emSign Root CA - G1, its other eMudhra root. Mozilla removed the ECC root on October 20. I expect both programs to drop the company entirely by the end of the year. A CA that submitted guessable keys to the root stores and went 18 months without noticing has a hard case to make at its next inclusion review, and the 1% revenue line reads like a company preparing to walk away from the business.

The cheap fix is on the root program side. Every certificate submitted to the CCADB, root or intermediate, should get a weak key scan before acceptance, and the scan should include small scalars, shared moduli and the Debian weak key list. The expensive fix is on our side. Revocation does not reach clients outside the browser, it never has, and this incident proves that a CA failure in 2026 is handled by rebuilding binaries and shipping OS packages, three days after the browsers were done. My prediction is that the next CA key failure gets found the same way, by one person on a weekend, and that it takes a week to reach the Linux boxes again.