Author: @ Deepak Kandpal
🔑 eMudhra's "Private Keys" Were Just Tiny Numbers: What Happened and What to Do

If you work anywhere near web security, your timeline has probably been full of one name this week: eMudhra. The headline was "private keys exposed", but the real story is stranger, and honestly a bit funnier (and scarier) than a normal leak.
I read through the Mozilla bug report, eMudhra's own statement, the Cloudflare write-up, and the coverage from BleepingComputer, CyberScoop, Help Net Security, CoinDesk, Endor Labs and others, so you don't have to. This post explains what actually broke, in plain words, and what you should check on your own machines and servers.
:: Enjoy the content☕ ::
Status as of 23 October 2026:
This is still developing. eMudhra has said its full root-cause report is coming, and Mozilla's questions to the company are still open. I'll point out where sources disagree.
First: Nothing Was "Stolen" 🕵️
When we hear "private key exposed", we picture a hacker breaking into a server and walking out with a file. That is not what happened here.
Security researcher Scott Helme put it best: "Normally when a CA key is compromised, someone stole it!" Here, the key was effectively public from the day the certificate was created, because anyone could work it out from the public certificate itself.
What is a private key, really?
A private key is just a number. Its whole security comes from one thing: that number being too big and too random to guess.
For the curve eMudhra used (P-384), a proper key is a random number of roughly 116 digits. Guessing it would take about 10¹¹⁵ tries. For comparison, there are around 10⁸⁰ atoms in the observable universe.
What researchers found instead was a number smaller than 256. One of them was literally the number 4.

Why It Matters:
If there are only 256 possible keys, you don't need a supercomputer. A laptop tries all of them in less than a second. Helme did exactly that. Mozilla later recovered the keys independently, without knowing the original reporter's method, and people reported getting an AI agent to do it from a single prompt.
Who Is eMudhra and What Exactly Was Affected? 🏢
eMudhra is an Indian company and one of India's licensed certificate authorities (CAs). It sells digital signatures, eSign, enterprise security, and, until now, TLS/SSL certificates that make the little padlock appear in your browser.
The problem sits in eight intermediate CA certificates:
| Intermediate | Purpose |
|---|---|
| EM DV TLS CA - G3B / G3C | TLS, Domain Validated |
| EM OV TLS CA - G3B / G3C | TLS, Organization Validated |
| EM EV TLS CA - G3B / G3C | TLS, Extended Validation |
| EM OV CS CA - G3B / G3C | Code signing (trusted by Microsoft) |
Each key actually has two certificates: one issued by eMudhra's own root, and one cross-signed by Sectigo. That is 16 certificates in total, all chaining to roots trusted by Apple, Google, Microsoft and Mozilla.
A Quick Detour: How Certificate Trust Works 📜
Your browser doesn't know every website on earth. It only trusts a small list of root CAs. Roots sign intermediates, intermediates sign the certificates for actual websites.
The intermediate's private key is the thing that signs those website certificates. So whoever holds an intermediate's key can sign a certificate for any domain they like, and it will look perfectly valid.

Risk: An attacker sitting between you and a server (public Wi-Fi, a hostile network, a compromised router) could present a forged certificate and impersonate the server. They don't break the encryption; they pretend to be the real site.
How Did This Even Happen? 🔬
eMudhra's preliminary explanation (posted on Mozilla's Bugzilla, bug 2083449) goes like this.
On 30 April 2025 the company held a key generation ceremony, the formal procedure where the CA creates its most sensitive keys inside a hardware security module (HSM). It created 24 intermediate CAs.
This time there was an approved deviation from the normal procedure: an extra "wrap/unwrap" test, because the keys were meant to be exported. A flaw in the code made the HSM create a second, weaker key pair. Then a very human thing happened. The labels on the strong and weak keys looked similar, so the weak ones were picked by mistake to create the certificate requests.

Those requests went to eMudhra's root and to Sectigo for cross-signing. The weak keys ended up in browser trust lists, and nobody noticed for roughly 18 months, through two independent audit cycles, by eMudhra's own account.
Key Insight:
eMudhra says the HSMs (FIPS 140-2 Level 3) themselves were not at fault, only one procedural step. Mozilla and other researchers are still asking whether the weak key was really generated inside the HSM or imported from somewhere else. That question is unanswered right now.
The Timeline ⏱️

The short version, all dates UTC:
- 17 Oct: A researcher known as Wayne notices the weak EC keys while testing against CCADB (the Common CA Database). He signs a message, "We have a problem here - Wayne", with each of the eight keys as proof and emails Apple, Google, Microsoft, Mozilla and eMudhra. Chrome blocks the six TLS intermediates within about 100 minutes of the report. Mozilla finishes its block by 22:59.
- 18 Oct: eMudhra revokes all eight, reason
caCompromise. - 19 Oct: Sectigo revokes its cross-signs. Apple blocks.
- 20 Oct: Microsoft blocks. Mozilla and Chrome go public.
- 21–22 Oct: eMudhra announces it is leaving the global SSL/TLS business.
- 27 Oct (expected): Chrome removes the affected root
emSign ECC Root CA - G3in Root Store v43.
eMudhra's chairman, V. Srinivasan, said the certificates were revoked within 14 hours of discovery, that no infrastructure was compromised and no data was breached, and that global TLS was only about 1% of revenue. He also cited rising compliance costs and free certificates from big providers. Reporting says the company's shares fell around 40% in the two days after disclosure, and Indian authorities have started an investigation.
So… Was Anyone Actually Attacked? 🤷
Nobody knows for sure, and that's the uncomfortable part. What we can say:
- eMudhra says it knows of no evidence the weak keys were exploited before disclosure.
- India's CERT-In reported no malicious use as of Wednesday.
- Cloudflare's review found no active exploitation on its services.
- But the keys were recoverable for about 17 months, and none of the parties can prove a negative.
There's one more clue, from Certificate Transparency (CT) logs. CT is a public record of certificates issued by CAs, and Chrome argues that because nothing from these six TLS CAs was in CT before the block, no forged certificate could have worked in a CT-enforcing browser. The first logged certificate from these CAs appeared on 19 Oct at 20:24 UTC, around 48 hours after Chrome's block.
After that, the logs filled up fast. The tracker at ctlogs.dev lists about 107,000 certificates from those CAs as of 23 Oct, and almost all of them are one name set:
I wouldn't read malice into that. Browsers reject them now, and the rest of the list includes obvious test names like .invalid domains and the researcher's own we-have-a-problem.com hosts. But it shows how trivial it became to mint certificates once the keys were known.
Security Note:
CT only protects clients that enforce it. Browsers do. Plenty of scripts, servers and CLI tools don't. That is where the real risk lives.
The Part Most People Will Miss: It's Not Just Browsers 💻
Browsers got fixed within hours because they get revocation data pushed to them. Plenty of other software never checks revocation at all. Helme's tests (via CoinDesk) found that curl, Python, Node, Go and Java all accepted a forged certificate for Stripe's API. So eMudhra and Sectigo revoking the intermediates doesn't help those clients. Only updating their trust store does.

Who is exposed?
| Where | Why | What to do |
|---|---|---|
| Servers and scripts using Go, Python, Node.js, curl, Java | Own or OS trust bundle, no revocation check | Update runtime and ca-certificates |
| Docker and containers | Old image = old CA bundle | Rebuild from a patched base and redeploy |
| Libraries with their own frozen PEM file | OS updates never touch them | Replace the bundle or point to a fresh one |
macOS built-in /usr/bin/curl |
Bundle doesn't check revocation (per Dennis Jackson, Mozilla) | Use a patched curl, for example via Homebrew |
| Systems verifying code signatures | emSign Root CS CA - G3 is trusted for code signing |
Review separately |
Endor Labs also warned about the sneaky ones: some HTTP client libraries ship their own certificate file, so even a fully patched OS can't save you. Dependency scanners usually miss these because they aren't versioned dependencies.
🛠️ What You Should Do Right Now
1. Test your own stack
The researcher behind the public disclosure runs a test site. Connect to it from the same environment your app actually runs in, not just from your laptop's browser:
curl -sS https://dv-g3b-emudhra.we-have-a-problem.com -o /dev/null
- A certificate error means that client rejects the compromised chain. Good.
- A successful connection means it still trusts it. Not good.
There is also a noct version of the test hosts whose certificates were never logged to CT, which tells you whether your client enforces Certificate Transparency.
2. Patch what's patchable
Versions that the trackers list as fixed (check the live tracker for your exact distro, since this list changes daily):
| Component | Fixed version |
|---|---|
| Go | 1.27.3 / 1.26.10 |
| Node.js | 26.12.1 / 24.22.1 / 22.23.4 |
Python certifi |
2026.10.19 |
Rust webpki-roots |
1.0.10 |
| Linux | Updated ca-certificates (Ubuntu, Alpine, Fedora, Arch, Gentoo, RHEL 8/9/10 and others) |
Heads Up:
Some packages were still pending when the articles I read were published (Debian, FreeBSD, Bun and Node.js in one report, RHEL 7 and Bottlerocket in another). Don't trust my table over the live tracker: emudhra.we-have-a-problem.com.
3. Don't "fix" certificate errors by turning verification off
Cloudflare said it plainly, and it bears repeating. If you start seeing new certificate errors after patching, do not switch off verification. That removes the exact protection the patch restores.
4. Look backwards if you handle sensitive traffic
Endor Labs suggests reviewing TLS inspection, proxy and endpoint logs for certificates issued by these eight intermediates, especially for clients that don't enforce CT and that send credentials. The keys were weak since April 2025.
⚠️ Where the Sources Disagree
News moves fast and a few details don't line up. These are the ones I noticed:
- Who found it? Mozilla's bug report and BleepingComputer credit Wayne. Some outlets credit Mozilla's Dennis Jackson, who made the public disclosure on 20 Oct.
- Revocation date. Mozilla's bug and eMudhra's own statement say 18 Oct. One outlet says 20 Oct. eMudhra's status page apparently had its own dates off by a day, and the Bugzilla thread asks them to correct it.
- Apple's block. Several sources say 19 Oct. The researcher's page lists 22 Oct, which may refer to additional protections.
- "How long is a normal key?" A couple of articles say 77–78 digits. That's the size for a 256-bit curve. For P-384 it is about 116 digits. Either way, "below 256" is absurdly small.
- How many certificates need migrating? eMudhra estimates around 30,000 (about 97% via ACME). Chrome's CT analysis counts about 30,800 unexpired precertificates chaining to the G3 root, almost all from two InCommon subordinate CAs. eMudhra says the distrusted ECC root serves one customer ecosystem in the United States.
💭 My Take
A few things stand out to me.
- The human factor is the story. Not a nation-state, not a zero-day. A code flaw, two similar labels, and a ceremony that didn't catch it. Two audit cycles also didn't catch it.
- A key being "compromised" doesn't need a breach. Weak randomness is a quiet failure that passes every "is the key present?" check.
- Revocation is weaker than we pretend. Browsers handled this in hours. Anything outside a browser depended on a software update, and some of that software is hiding in container images and vendored cert files.
- Certificate Transparency saved a lot of skin. The fact that browsers require a certificate to be publicly logged is probably the main reason this wasn't a much worse week.
If you remember only one thing: patch your trust stores, rebuild your images, and test from the place your code really runs.
❤︎ Stay tuned for more exciting content !
📚 Sources
- Mozilla Bugzilla 2083449: eMudhra private key compromise of intermediate certificates
- eMudhra: Statement on recent certificate security incident
- Cloudflare: 8 eMudhra certificates are compromised
- Researcher disclosure and affected software tracker
- ctlogs.dev: eMudhra intermediate CA compromise
- Help Net Security
- CyberScoop: eMudhra exits the certificate business
- BleepingComputer
- CoinDesk
- Endor Labs: trust stores you patched and the ones you didn't
- MediaNama: explainer and India angle