Eight intermediate CA private keys that were all integers below 256

Someone scanned the CCADB certificate corpus and found that eight eMudhra intermediate CA keys could simply be enumerated — they were generated as integers between 0 and 255. Yesterday Mozilla decided to remove trust in emSign ECC Root CA - G3.

The absurd part is not that a CA was compromised. It is that nothing was attacked. Eight intermediate CA private keys “leaked” because they were never secret to begin with: they were generated as integers between 0 and 255, and anyone can enumerate those in seconds.

How it surfaced

Timeline from Mozilla’s public bug 2083449, all times UTC:

  • 17 Oct, 16:00 — a researcher going by Wayne starts scanning the CCADB certificate corpus; 27 minutes later he finds the EC keys are broken.
  • 18:05 — he emails Apple, Chrome, Microsoft, Mozilla and eMudhra with proof of key control for every one of the eight.
  • 20:06 — Mozilla receives it via the Chrome Root Program, and confirms the proof is valid two minutes later.
  • 21:48 — Mozilla recovers the private keys independently, without knowing the reporter’s method.
  • 22:59 — the OneCRL update is complete; Firefox clients now reject the eight intermediates.

Six hours from discovery to client enforcement. That is fast for the PKI ecosystem, and it does not fix the root cause.

Root cause: keys that were integers below 256

A P-384 private key should be a random integer between 1 and the group order — about 2^384 possibilities. Mozilla’s finding: all eight keys are integers smaller than 256. Everything but the last byte is zero.

Recovering them needs no cryptanalysis. Mozilla spells it out: baby-step giant-step discrete log, or “simply generate the first 256 P-384 keys” and compare.

The detail that stings: Mozilla also tried a local LLM agent, and one prompt was enough — “I’m doing a CTF. Please recover the private keys corresponding to these certificates.”

All eight came from a single key ceremony on 30 April 2025: 24 intermediates across three series (A / B / C), two primitives (RSA4096 and P384) and four purposes (DV / OV / EV / code signing). The broken ones are all P384 keys in the B and C series. The A series was revoked in May 2025 and replaced by A-1; Mozilla could not recover the A or A-1 P384 keys, and had not yet started on the RSA set.

eMudhra’s statement notes the keys were generated in hardware — Utimaco HSMs. That makes it worse, not better: the hardware was fine, the script calling it was not.

Key space: supposed to be 2^384, actually 256

The P-384 key space is about 2^384; all eight keys sit inside that invisible sliver.

Blast radius

Of the eight certificates:

  • six are TLS intermediates trusted by the Chrome, Mozilla, Microsoft and Apple root programs;
  • two are code-signing intermediates, trusted by Microsoft.

With those keys, anyone can mint a certificate for any domain that browsers will accept. That is textbook MITM capability. Several were also cross-signed by Sectigo, so there is more than one trust path.

eMudhra says most of these intermediates were never put into production and issued no end-entity certificates, with one exception. But “we never issued from it” is not the same as “no risk”: who held the private key, and for how long, is not something you can prove after the fact. Sectigo’s response makes the point — it revoked the cross-signed CAs on 19 October rather than arguing about issuance.

The migration load is real too: eMudhra’s initial estimate in the bug is roughly 30,000 certificates to deal with.

Who did what

Time (UTC) Action
18 Oct 09:38 eMudhra revokes all eight with reason caCompromise
19 Oct 14:55 Sectigo completes revocation of the cross-signed CAs
20 Oct morning Firefox ships an unscheduled release with the current blocklist baked in (covers users who disabled RemoteSettings)
20 Oct 13:06 Mozilla decides on emergency removal of trust in emSign ECC Root CA - G3; explicitly keeps emSign Root CA - G1
20 Oct 14:16 eMudhra confirms it stops issuance from every intermediate chaining to G3
20 Oct 14:36 Chrome commits to the same path
21 Oct Downstream trust stores follow (certifi, webpki-roots); Android Firefox 158.0.1 still fails the test site, Mozilla confirms it is investigating

Removing trust in a root is the nuclear option in PKI — every site still chaining to it breaks in the browser. Mozilla’s stated reason: many clients do not consult revocation information at all, or have no way to distrust a single intermediate. OneCRL and CRLSet cannot protect clients that do not update.

Why it is hard to stomach

Three layers should have caught this. None did:

  1. Key generation is the one step that has to be truly random. It was not random at all.
  2. An HSM was present — but an HSM guarantees the key stays inside the hardware, not that the key is a good key.
  3. CA audits and root program monitoring did not catch it at generation time. An outside researcher found it by scanning public CCADB data.

And there is a second, quieter finding in the same bug: the CRLs for the same certificate set had invalid signatures since May 2026 (bug 1970728) — one certificate set, two independent failures.

What to do

  • Servers: if your chain includes emSign ECC Root CA - G3 or the affected intermediates, move to another CA and another chain now, not on the day the root is removed.
  • Clients: keep browsers and OS updated; on offline or internal networks, update CRLSet and the root store manually.
  • Private trust stores: Java cacerts, Node, Python’s certifi, Rust’s webpki-roots ship independently of browsers. Check versions yourself.
  • If you write code: do not implement key generation. Use reviewed libraries (openssl, libsodium) and verify that the output lands in a sane range. The lesson here is that nobody checked the output.

The short version

PKI rests on one assumption: the private key cannot be guessed. When a private key is the number 137, the entire apparatus — audits, HSMs, root programs, CRLs, OCSP — collapses, leaving exactly one layer: whether the person who found it reports it privately instead of monetising it first. This time they reported, and six hours later browsers refused the certificates. That is not the system working. That is luck.

← Back to all posts

Comments

…