← who art thou
Network Working Group
Saksham
Reworking Fundamentals in Computing: 0004
saksh.fyi
Category: Informational
October 2026

4, No Reason

Status of This Memo #

This memo provides information for the curious and the on-call. It does not specify an Internet standard of any kind. Distribution of this memo is unlimited, and comments are welcome by email (saksh.am [at] outlook [dot] in). I don’t trust comment boxes online.

Abstract #

On 17 October 2026 a researcher reported that the private keys of eight intermediate CA certificates run by eMudhra (emSign) were tiny numbers that anyone could recover by trying 255 candidates. This memo explains just enough about how an elliptic curve key is made to see why a tiny one is fatal, and then walks through what went wrong, how Chrome and Firefox responded within hours, and who is still exposed.

Table of Contents #

1. Introduction #

Like RFC 0003, this one is not theory. It happened this week, the post-mortems are still being written, and it is a serious incident, so I am writing it down while it is fresh.

The short version: a certificate authority trusted by every major browser and operating system created eight intermediate CA certificates whose private keys were tiny integers. A guessable key is not a key.

A note on freshness: everything about the incident comes from public sources dated 17 to 21 October 2026 (see References). eMudhra’s explanation is preliminary, and details may have changed by the time you read this.

2. Background: Who Is Allowed to Say “This is google.com” #

When your browser opens an HTTPS site, the server presents a certificate. Your browser does not know the server, so it asks: who vouches for this? The answer is a chain.

Root CA              (pre-installed in your OS / browser trust store)
  └── Intermediate CA (signed by the root)
        └── Leaf certificate (the website's)

How does my browser or OS accept this certificate?

A certificate is public, and it carries the server’s public key. The private key never leaves the server. Two checks happen. First, the certificate has a signature made with the intermediate’s private key. The browser takes the intermediate’s public key (from the intermediate certificate, which the root signed, and the root’s public key is already in the OS or browser trust store) and verifies that signature over the certificate’s contents: the domain, the server’s public key and the validity dates. If any byte was changed, the signature fails. Second, in the TLS handshake the server signs something with its own private key, which proves it holds the key that matches the public key in the certificate.

So the intermediate’s private key is the one that says “this domain really owns this public key”. Whoever holds it can sign that sentence for any domain, and the browser will accept it. That is why a CA’s key handling is held to a standard well above “a password in a vault”. Figure 1 shows the whole chain (it calls the leaf certificate the end-entity certificate).

Chain of trust diagram: the root certificate is self-signed, the root signs the intermediate certificate, the intermediate signs the end-entity certificate, and each step is checked with the issuer’s public key.
Figure 1. Each certificate is signed with its issuer’s private key and verified with the issuer’s public key. Diagram: “Chain of trust v2” by Fanyangxi, Wikimedia Commons, CC BY-SA 4.0, unchanged.

The root key stays offline. Day-to-day signing is done by intermediates, so that if one leaks you can revoke it and the root survives.

2.1 When a new root or intermediate appears

What if a new root or intermediate shows up tomorrow?

A new root is not trusted until a vendor says so. The trust store is a list curated by the OS or browser vendor (Mozilla, Chrome, Apple and Microsoft each keep their own), and a root only joins it after review and an update. Your system never discovers roots by itself, which is also why the fix for this incident reached people as updates.

A new intermediate needs no update. The server sends its chain in the TLS handshake, and the browser checks that each certificate was signed by the next one, ending at a root already in the store. If the chain holds, it is accepted. That is why one weak intermediate key is as bad as a weak root: anything a trusted root signs is trusted automatically.

3. How an Elliptic Curve Key Is Made #

These certificates used P-384, an elliptic curve with a 384-bit field. The curve maths itself is not needed here, only the shape of how a key pair is made.

The curve is P-384 (also called secp384r1), a standard NIST curve whose parameters are public. The signature algorithm is ECDSA: the intermediate uses its private key d to sign certificates, and anyone can check the signature with Q. Neither is weak. What failed was the choice of d.

A caveat: I am really no expert on elliptic curve cryptography. This is my best understanding of it, so read it as one learner’s notes and not a reference. Corrections are welcome by email.

3.1 Domain parameters

Everyone using the curve agrees on these. They are fixed by a standard, public and not secret.

3.2 The steps

  1. Pick the curve and G. For P-384 these come from the standard.
  2. Pick the private key d: a random integer in [1, n−1]. This is the only secret, and the only step that needs randomness.
  3. Compute the public key Q = d × G. “Multiplying” a point means adding it to itself d times, done efficiently by double-and-add.
  4. Validate Q. It must not be infinity, it must satisfy the curve equation, and n × Q must be infinity.
  5. Export. The private key stays in the HSM. Q goes into a certificate signing request, the root signs a certificate for it, and the resulting intermediate carries Q in public.

Look at steps 3 and 4 above. Nothing in them can tell that d is bad. d = 4 is a valid key: it is inside the range, Q lands on the curve, and the order check passes. The maths has no concept of “too small”. The only protection is step 2, drawing d from the whole range.

4. What Went Wrong #

All eight affected certificates used P-384 (ECDSA) keys generated in April 2025. According to Mozilla’s incident report, the private keys had values smaller than 256.

The public key Q = d × G sits inside the certificate. When d is huge, working out d from Q is infeasible. When d is below 256, there are only 255 candidates to try.

This is not factoring (that is the hard problem behind RSA). It is the discrete logarithm problem: given G and Q, find d. The same shape shows up with plain numbers. Take 34 mod 17 = 13. Someone who only sees 13 (that is Q) has to try 31 = 3, 32 = 9, 33 = 10, 34 = 13, and finds the exponent is 4. With a huge exponent that search is hopeless. With a tiny one it ends almost at once.

One of the keys, for “EM OV TLS CA - G3C”, was exactly 4. (The certificate that turned out to be live was a different one, the DV G3C.) Mozilla staff recovered the keys independently, with no hints, within roughly two hours of receiving the report.

The eight certificates:

The six TLS ones are trusted by the Chrome, Mozilla, Microsoft and Apple root programs. The two code-signing ones are trusted by Microsoft.

5. Recovering the Key #

The attack is step 3 of Section 3.2 run in a loop. Here it is against a stand-in public key, with the secret set to 4 like the real one:

# pip install cryptography
from cryptography.hazmat.primitives.asymmetric import ec

target = ec.derive_private_key(4, ec.SECP384R1()).public_key().public_numbers()

for d in range(1, 256):
    pub = ec.derive_private_key(d, ec.SECP384R1()).public_key().public_numbers()
    if (pub.x, pub.y) == (target.x, target.y):
        print("private key is", d)
        break
private key is 4

On my machine this finished in about a tenth of a second, including interpreter start. It stops early because the secret is 4. A secret near 255 would take the full 255 iterations, still well under a second. Nothing here is specific to eMudhra: it is just what a small private key means. The real question is how such keys got into a production CA.

6. The Cross-Sign Twist #

So that older devices without eMudhra’s newer roots would keep working, each of the eight intermediates was also cross-signed by Sectigo under its AAA Certificate Services root. That gives a second certificate with the same public key, and so the same weak private key, chaining to a different and very widely trusted root.

That matters because “remove the eMudhra root” is not enough. An attacker who forges a certificate with the weak key can attach the Sectigo cross-signed intermediate instead, and the chain still ends at a root clients trust.

So the real fix is to distrust the key, not just the root. Browsers do this with SPKI hashes (hashes of the public key information), which catches both certificates at once. The Go project hardcoded distrust of the eight keys into its standard library for the same reason.

7. The Timeline #

All times UTC, from Mozilla’s Bugzilla report and the browser vendors’ posts.

WhenWhat
17 Oct, 18:05Chrome Root Program receives a report from a researcher known as Wayne.
17 Oct, 19:45Chrome corroborates the findings and ships a CRLSet update blocking the eight SPKI hashes.
17 Oct, 20:06Mozilla receives the report, forwarded by Chrome. Apple and Microsoft are also notified.
17 Oct, ~21:28eMudhra acknowledges the issue. The thread notes that “EM DV TLS CA - G3C” was live and was disabled.
17 Oct, ~21:48Mozilla independently recovers the keys and sends proof.
17 Oct, by 22:59Mozilla’s OneCRL block has reached Firefox users with standard settings.
18 Oct, ~09:24–09:40eMudhra revokes all eight with reason cACompromise.
19 OctApple devices block the certificates.
20 OctMicrosoft blocks them. Mozilla ships Firefox 158.0.1 and NSS 3.131.1, which removes emSign ECC Root CA - G3. Chrome removes the same root from the Chrome Root Store. Public advisories go out.

From report to a Chrome or Firefox block took a couple of hours, and Apple and Microsoft followed within three days. Credit where due: the disclosure and response machinery worked.

8. Who Is Actually at Risk #

Browsers. Chrome, Firefox, Safari and Edge enforce Certificate Transparency (CT): a certificate has to appear in public logs to be accepted. The incident tracker by Mozilla engineer Dennis Jackson reports no CT log entries for these intermediates in the relevant period. A forged certificate that CT-enforcing clients accept has to be logged, so an attack on them would have left public evidence.

Everything else. Many clients outside the browser ecosystem do not enforce CT, and many do not check revocation at all. That includes plenty of language runtimes, command-line tools, containers, embedded devices, and Linux distros that ship the Mozilla bundle. A revocation entry means nothing to a client that never looks at it, so those need a software update or a manual distrust.

The attack still needs an interception position (a man-in-the-middle), so this is not “anyone on the internet can read your traffic”. But for anyone in the path, any HTTPS site is on the menu.

Was it exploited?

Unknown. The keys have now been published, and nobody has shown whether they were abused earlier.

9. What eMudhra Says #

From its Bugzilla response and a statement dated 20 October (preliminary):

10. Checking My Own Machine #

My own system (Ubuntu 24.04) had the emSign roots in /etc/ssl/certs, which is normal. What matters is whether the package carries the fix and whether emSign ECC Root CA - G3 and the AAA root are gone. The incident tracker lists 20260816ubuntu0.24.04.1 as the fixed ca-certificates version for 24.04, and that is what apt policy ca-certificates showed after updating.

sudo apt update && sudo apt install --only-upgrade ca-certificates
apt policy ca-certificates

The update printed 4 added, 5 removed from the rehash, plus a rehash: warning: skipping ca-certificates.crt line. The warning is harmless: that file is the concatenated bundle containing many certificates, so rehash skips it. To confirm both affected roots were gone:

ls /etc/ssl/certs | grep -i -E 'emsign_ecc_root_ca_-_g3|comodo_aaa'

Empty output. Both emSign ECC Root CA - G3 and the AAA Certificate Services root were removed from the system store. (The file is named Comodo_AAA_Services_root, because Sectigo used to be Comodo CA.)

Two caveats. Removing the AAA root can break sites or tools whose chains end only there. And tools that ship their own CA lists (Node.js, Python’s certifi, Docker images, Go binaries built before the fix) need their own updates. For anyone who cannot update yet, the tracker gives a manual distrust (it says this is not recommended for ordinary users). This edits your system trust list, so back up /etc/ca-certificates.conf first; the -i.bak below keeps a copy, but check that it exists before relying on it:

sudo sed -i.bak \
  -e 's|^mozilla/emSign_ECC_Root_CA_-_G3.crt|!&|' \
  -e 's|^mozilla/Comodo_AAA_Services_root.crt|!&|' \
  /etc/ca-certificates.conf && sudo update-ca-certificates

11. Conclusion #

A CA’s whole product is the claim that its keys are secret. Here the secret was a number you could guess on a napkin.

It also loops back to RFC 0001: a bad value quietly looked like a good one, nothing said so, and it was an outside researcher who finally noticed. A trivial sanity check would have said it in seconds.

12. References #

[MOZ-BLOG] Mozilla, “Protecting Firefox users following the compromise of eMudhra intermediate certificates”, blog.mozilla.org/security.

[CHROME-BLOG] Google, “Protecting Chrome and Android Users from Compromised eMudhra Intermediate CA Certificates”, blog.google/security.

[BUG-2083449] Mozilla Bugzilla 2083449, “Private key compromise of eMudhra Intermediate Certificates”, bugzilla.mozilla.org/show_bug.cgi?id=2083449.

[TRACKER] Dennis Jackson, “eMudhra Intermediate CA Compromise”, emudhra.we-have-a-problem.com.

[BC] BleepingComputer, “Mozilla, Google, Apple block compromised eMudhra CA certificates”, bleepingcomputer.com.

[THN] The Hacker News, “Eight eMudhra CA Keys Compromised, Triggering Emergency Fixes Across Browsers and Software”, thehackernews.com.

[LWN] LWN.net, “eMudhra intermediate CA compromise”, lwn.net/Articles/1101643.

[BUG-1970728] Mozilla Bugzilla 1970728, “eMudhra: Invalid CRL signatures”, bugzilla.mozilla.org/show_bug.cgi?id=1970728.

[RFC0001] Saksham, “Observability, My Dear Watson”, blogs.saksh.fyi.