TRENDING
Unpopped corn kernels mixed with popped popcorn on a white surface
October 28, 2026
How to Stop Decompression Bombs in Python With Hard Output Limits for gzip, Brotli, zstd, ZIP, and tar.gz
Ouroboros, a polished stainless steel sculpture of two interlocking loops with a pierced surface, standing beside a dark pool under trees
October 28, 2026
Anthropic’s S-1 Puts Safety Audits Inside the “Closing the Loop” Cycle It Warns About, and Says Its Evaluations Could Overstate Safety
Two opened leaves of the Verona palimpsest, with an older, darker layer of writing still showing through the newer script written over it
October 28, 2026
Cloudflare Says Its GLM-5.3 Model Returned Other Customers’ Data in 155 Responses, and a Public SGLang Bug Report Had Described the Same Path Since July
A raft of long grey wooden logs lying in a green meadow, with a forked post standing in the middle
October 28, 2026
How to Build the Raft Consensus Algorithm in Python and Test It With Crashes, Partitions, and Planted Bugs
Open handwritten account book from the Brussels Confraternity of the Seven Sorrows (1499 to 1516), with entries running down each page and blank space below them
October 28, 2026
Anthropic’s S-1 Puts $52.9 Billion More on Three Named Compute Commitments Than Its October 9 Draft Did, and Still Leaves Its Contractual-Obligations Table Blank
28 Oct 2026
SXZ.io SXZ.io
  • Home
Search the Site
Popular Searches:
Technology Amazon AI
Recent Posts
Vintage silver stopwatch with a chain on a black background, its dial showing seconds from 5 to 60
How to Find a Slow Query in PostgreSQL 18 With pg_stat_statements, Read Its EXPLAIN ANALYZE Plan, and Fix It With the Right Index
October 27, 2026
A wooden Tower of Hanoi puzzle on a market table, with three pegs and stacked discs of different sizes
Two Labs’ Claimed Refutations of the Exponential Time Hypothesis Turn Verification Into a Statement-Reading Problem, and Their Lean Theorems Promise Only That a Constant Exists
October 27, 2026
Two earthworms lying together on wet brown leaf litter, photographed close up
Tailscale Merged Fixes for Most of the 11 “Tailworm” Findings Before Shipping a Release, and the Forwarding Switch It Recommends Already Exists in the Shipped Client
October 27, 2026
SXZ.io SXZ.io
  • Home

Categories

Articles 268 Posts
News 271 Posts
Learning Hub 241 Posts
Home/News/Eight eMudhra CA Keys Were Single-Byte Numbers, Chrome and Firefox Blocked Them in Hours, and Chrome Plans to Drop the Root October 27
News

Eight eMudhra CA Keys Were Single-Byte Numbers, Chrome and Firefox Blocked Them in Hours, and Chrome Plans to Drop the Root October 27

Eight eMudhra intermediate CA keys were whole numbers below 256; Chrome and Firefox blocked them within hours and Chrome plans to drop the ECC root on October 27, but OpenSSL-based clients and older...

October 22, 2026 13 Min Read
45

Eight private keys behind publicly trusted CA certificates turned out to be whole numbers below 256. The certificate authority is eMudhra, an Indian company that sells TLS certificates under the emSign brand, and the keys belong to six TLS and two code-signing intermediate CAs it created at a key ceremony on April 30, 2025. Anyone can recover such a key from the public certificate by multiplying the P-384 base point by each integer from 1 to 255 until the result matches the certificate’s public key. We ran that check on all eight certificates: every one matched, and the whole search took 0.26 seconds on the machine that built this post.

Table Of Content

  • What the public record shows
  • What we checked ourselves
  • Which clients still accept the chains
  • eMudhra’s explanation and the June 2025 CRL error
  • Who has to act before October 27
  • What is still open
  • Sources and method

A researcher who goes by Wayne emailed the Apple, Chrome, Microsoft and Mozilla root programs and eMudhra at 18:05 UTC on October 17, by their own log. Chrome’s blog gives the same time for its copy, and Mozilla logged its copy at 20:06 after Chrome forwarded it. Chrome landed a block at 19:45 UTC and Mozilla finished its Firefox block at 22:59 UTC. Mozilla’s trust list (NSS 3.131.1) no longer carries the emSign ECC root that signed the eight certificates, Chrome says its own removal should reach every device that uses the Chrome Root Store on the morning of Tuesday, October 27, Pacific time, and eMudhra says it has stopped issuing from every intermediate under that root. Blocking the keys protected Chrome users, and Firefox users with standard settings, within hours. It did nothing for clients that never receive a browser’s blocklist, and several of the clients we tried on October 22 still accepted the compromised chains.

What the public record shows

The table follows the record from the key ceremony to Chrome’s planned removal. Times are UTC. Most of it comes from Mozilla’s incident bug 2083449, Chrome’s security blog post and Dennis Jackson’s incident site. Jackson is a Mozilla cryptography engineer.

When What happened Source
April 30, 2025 eMudhra’s key ceremony creates 24 intermediate CAs in three series, A, B and C. The eight weak keys are the P-384 keys of the B and C series. Their certificates are valid until April 28, 2040. Bug 2083449, comments 5 and 11; certificate fields
May 14, 2025 Sectigo’s cross-signed copies of the eight keys, issued under its AAA Certificate Services root, start on this date and expire on December 31, 2028. Jackson’s certificate list
May 29 to June 6, 2025 By eMudhra’s dating, six CRLs it published on May 29 carry signatures that do not verify. A report on Mozilla’s tracker flags them on June 5, and corrected CRLs appear on June 6. Bug 1970728
October 17, 2026, 18:05 Wayne emails Apple, Chrome, Microsoft, Mozilla and eMudhra a report with a signed proof for each key. Chrome blog; bug 2083449, comment 2
October 17, 19:45 Chrome corroborates the findings and lands a CRLSet update that blocks the keys by public-key hash, which covers every certificate that shares those keys. Chrome blog
October 17, 20:06 to 22:59 Mozilla receives the report through Chrome at 20:06, acknowledges it at 20:08 and confirms the proofs are valid, recovers the keys on its own at 21:48 and completes the OneCRL block at 22:59. eMudhra acknowledges at 21:29 and says it has told Sectigo. Bug 2083449, comment 0
October 18, 09:24 to 09:38 eMudhra revokes the eight intermediates with the reason cACompromise. eMudhra’s table (comment 10); live CRL, checked by us
October 19 Sectigo says at 14:55 that it has finished revoking the eight cross-signed copies, and Mozilla reports at 19:50 that it has begun telling downstream trust-store operators. Apple blocks the keys. Go 1.27.3 ships with unnamed crypto/x509 security fixes, and Jackson’s tracker lists it as Go’s fix for this incident. Comments 13 and 14; Jackson’s site; Go release history
October 20 Microsoft blocks the keys. At 13:06 Mozilla announces it will remove the emSign ECC root after learning that several people had independently recovered the keys, and eMudhra stops issuing under that root at 16:27. Jackson’s site; comments 18 and 21
October 21 eMudhra posts “Update 3” on its status page. At 20:38 Chrome’s root program sends the company twelve questions. eMudhra status page; comment 30
October 27 (expected) Chrome Root Store v43, which removes the root, reaches stable Chrome. Chrome blog

What we checked ourselves

Jackson’s site publishes the eight certificates, the signatures Wayne made with each key and a JSON list of the intermediates. We used only those public files and the live revocation lists.

  • The proofs hold. All eight signatures over the message We have a problem here - Wayne verify under the public key in the matching certificate, as ECDSA with SHA-384. We checked them with pyca/cryptography 50.0.1 and cross-checked one with the openssl dgst command from Jackson’s page on OpenSSL 3.5.7, which printed Verified OK.
  • The keys are tiny. Each public key equals a small multiple of the P-384 base point. The smallest multiple is 4, the value Scott Helme reported, and the largest needs eight bits. Finding all eight took 255 point multiplications. Our own arithmetic puts the chance that a uniformly random 384-bit key lands below 256 at about one in 2 to the power of 376, so these were not random draws.
  • The check needs no AI. eMudhra’s status page says the researcher found the weak keys “reportedly with the help of AI-assisted tooling,” and Jackson and Helme each report that an AI agent recovered the keys from a short prompt. The search above is a loop of 255 multiplications, and it ran without a model.
  • The certificates outlive the incident. The eight intermediates are valid until April 28, 2040, so a client that applies no blocklist, revocation or root removal could keep accepting chains through them for years.
  • The revocations are real. eMudhra’s live CRLs list all eight serials with the reason cACompromise, with revocation times from 09:24:32 to 09:38:46 on October 18. Sectigo’s AAA CRL, issued at 05:39 UTC on October 22, lists all eight cross-signed copies with the same reason.
  • Mozilla’s list has dropped the root. The CA bundle that curl publishes, which says it carries Mozilla’s certificate data as of 13:32 UTC on October 20, contains no emSign ECC Root CA - G3 and no AAA Certificate Services, and still contains emSign Root CA - G1.

Which clients still accept the chains

Jackson runs two kinds of test host for each intermediate: one that serves the direct eMudhra chain and one that serves the Sectigo cross-signed chain. At 10:14 UTC on October 22 we tried one of each from a Windows 11 machine with Git for Windows and Python 3.13.14.

Client and trust source Direct eMudhra chain Sectigo cross-signed chain
curl 8.21.0 on Schannel (Windows’ own verifier) Rejected, CRYPT_E_REVOKED Rejected, CRYPT_E_REVOKED
Python 3.13.14 ssl with the Windows root store Rejected Accepted
requests 2.34.2 with certifi 2026.07.22 Accepted Rejected
requests 2.34.2 with certifi 2026.10.19 Rejected Rejected
OpenSSL 3.5.7 s_client with Git for Windows’ CA bundle Accepted Accepted

Two things stand out. The clients that stayed silent are the ones that trust a bundle on disk and do not look up revocation, the pattern Helme describes, so eMudhra’s and Sectigo’s revocations did nothing for them and updating the bundle is what changes the answer. And the answer depends on which root a client happens to hold. The Windows store, as Python reads it, holds 43 roots including AAA Certificate Services but not emSign ECC Root CA - G3, so Python rejected the direct chain and accepted the cross-signed one. Sectigo said on Mozilla’s bug that the root behind its cross-signs “has already been removed from the Chrome and Mozilla root stores for some time” and “remains trusted within Microsoft and Apple root programs.” curl on Schannel refused both chains. We did not separate whether Windows’ own block or a revocation lookup produced that error.

Jackson’s page gives two curl commands, and a certificate error means the client does not trust the compromised intermediates:

curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/

On our machine both failed:

curl: (35) schannel: next InitializeSecurityContext failed: CRYPT_E_REVOKED (0x80092010) - The certificate is revoked.
curl: (35) schannel: next InitializeSecurityContext failed: CRYPT_E_REVOKED (0x80092010) - The certificate is revoked.

To test a Python environment, save this as trust_check.py. It sends one request to each test host, so run it only against these hosts, which exist for this purpose:

import requests

HOSTS = [
    "dv-g3b-emudhra.we-have-a-problem.com",
    "dv-g3b-aaa-emudhra.we-have-a-problem.com",
]

for host in HOSTS:
    try:
        r = requests.get(f"https://{host}/", timeout=20)
        print(f"{host}: STILL TRUSTED (HTTP {r.status_code})")
    except requests.exceptions.SSLError:
        print(f"{host}: rejected")

In a fresh virtual environment with certifi pinned to 2026.07.22, then upgraded, the output changed like this:

python -c "import certifi; print(certifi.__version__)"
python trust_check.py
pip install --upgrade certifi
python -c "import certifi; print(certifi.__version__)"
python trust_check.py
2026.07.22
dv-g3b-emudhra.we-have-a-problem.com: STILL TRUSTED (HTTP 200)
dv-g3b-aaa-emudhra.we-have-a-problem.com: rejected
2026.10.19
dv-g3b-emudhra.we-have-a-problem.com: rejected
dv-g3b-aaa-emudhra.we-have-a-problem.com: rejected

For anything that verifies against a bundle file, point OpenSSL at that file. The first line of output below came from Git for Windows’ bundle, which still holds the root. The next two came from the certifi 2026.10.19 bundle, which does not:

H=dv-g3b-emudhra.we-have-a-problem.com
echo | openssl s_client -connect $H:443 -servername $H -CAfile /path/to/ca-bundle.crt -verify_return_error 2>&1 | grep -E 'verify error|Verification'
Verification: OK
verify error:num=20:unable to get local issuer certificate
Verification error: unable to get local issuer certificate

eMudhra’s explanation and the June 2025 CRL error

eMudhra has given two accounts. On Mozilla’s bug on October 19 an eMudhra contact wrote that its review of the ceremony script and the HSM so far indicated that “a set of original ECC keys were created onboard as expected,” that “an approved deviation to our usual KGC to test a wrap/unwrap was introduced as these keys were meant for export for this instance,” and that “a flaw in the code resulted in the second pair of keys being created onboard which were weaker.” The weaker pair, the contact wrote, was “used by mistake to create the csr (because the key labels were similar) and signed by our root,” and “the CSR from these weaker keys were also sent over to Sectigo for cross signing.” The company says its Utimaco HSMs were not used for any other key material and that the device does not look to be at fault.

The status page adds that “the weak keys were the ones published to the browser root stores,” that the issue “went undetected for about 18 months, through two independent audit cycles,” and that eMudhra is “not aware of any evidence that the weak keys were recovered or exploited by anyone before the issue was disclosed.” It also says eMudhra has not yet confirmed the exact root cause.

That account connects to an earlier incident. On June 5, 2025 a report on Mozilla’s bug tracker, citing crt.sh’s check of Mozilla’s CA disclosures, flagged six eMudhra CRLs, one for each TLS intermediate, with invalid signatures; eMudhra’s own report says Sectigo raised it. In its full incident report eMudhra blamed a manual CRL step that “incorrectly referenced a non-corresponding CA key configuration,” said the keys “did not match the exact keys expected for those Intermediate CA CRLs,” and fixed it by “regenerating the CRLs using the appropriate private key associated with each Intermediate CA.” On October 19 the company wrote that the CRLs “were signed with the original private keys (which were supposed to be the correct keys with appropriate entropy) but given that this resulted in incorrect signatures, they were resigned with flawed keys.” By eMudhra’s own account, then, the keys it meant to use did not match the certificates it had issued, and the June fix made the CRLs verify by signing them with the flawed keys that were in the certificates.

Chrome’s root program has asked why eMudhra re-signed the CRLs “rather than halting operations, auditing why two key pairs existed for these CAs from the April 30, 2025 KGC, and revoking the certificates,” and why the June report left out that two key pairs existed. At the time of writing those questions had no public answer.

Two parts of the status page are worth setting against the record. It says eMudhra was made aware “late evening, India time” on October 18 and revoked the intermediates on October 19. Mozilla’s bug has eMudhra acknowledging the report at 21:29 UTC on October 17, and eMudhra’s own table shows all eight revoked on October 18, which the live CRLs confirm; a commenter on the bug has asked the company to correct or explain the difference. The page also says the impact is “contained to a single customer ecosystem in the United States,” and the next section shows where the certificates are.

Who has to act before October 27

Mozilla’s Jackson wrote that removing emSign ECC Root CA - G3 “will protect clients which do not use revocation information or lack a mechanism to withdraw trust in specific intermediates,” and that Mozilla is not removing trust in emSign Root CA - G1 for now. Chrome says it is “closely investigating the ongoing inclusion of eMudhra’s remaining CA certificates” in its store. For the removed root, Chrome’s count from Certificate Transparency data on October 21 found about 30,800 unexpired precertificates chaining to it. Of those, 30,791 came from two Internet2 InCommon subordinate CAs, InCommon Intermediate CA - OVG3C with 23,806 and InCommon Intermediate CA - DVG3C with 6,985, and 18 came from eMudhra’s own intermediates. Stanford’s IT page says its certificates have come from eMudhra’s CERTInext service since July 10, 2026, under InCommon intermediates, replacing the InCommon and Sectigo service that was decommissioned on July 17. eMudhra estimates that about 30,000 certificates need migration, about 97 percent of them issued by ACME, and says it is moving them to the hierarchy under emSign Root CA - G1.

Chrome has pointed out that standard ACME clients “do not automatically replace certificates outside their configured renewal window without ACME Renewal Information support or manual intervention,” which is the kind of renewal-timing assumption we covered in our post on Let’s Encrypt’s 64-day default. To see which hierarchy a server presents, print its chain and read the last issuer line:

H=example.edu
echo | openssl s_client -connect $H:443 -servername $H 2>/dev/null | grep -E '^ *[0-9]+ s:|^ *i:'

On Jackson’s direct test host that prints three certificates, and the last issuer line names the removed root:

 0 s:CN=dv-g3b-emudhra.we-have-a-problem.com
   i:C=NL, O=eMudhra BV, CN=EM DV TLS CA - G3B
 1 s:C=NL, O=eMudhra BV, CN=EM DV TLS CA - G3B
   i:C=IN, O=eMudhra Technologies Limited, CN=emSign Root TLS CA - G3
 2 s:C=IN, O=eMudhra Technologies Limited, CN=emSign Root TLS CA - G3
   i:C=IN, OU=emSign PKI, O=eMudhra Technologies Limited, CN=emSign ECC Root CA - G3

For everything else, the steps are the ones the incident sites give:

  1. Update whatever ships a CA bundle: the operating system’s ca-certificates package, certifi, Node.js, Go (and rebuild Go binaries), Java, curl’s bundle and pip. Jackson’s patched-software table lists fixed versions, for example certifi 2026.10.19, Go 1.27.3 and 1.26.10, Node.js 22.23.4, 24.22.1 and 26.12.1, and pip 26.2.2. When we last read it, at 10:26 UTC on October 22, Bottlerocket, Bun and Erlang’s certifi were still marked pending. Jackson also notes that the curl, git and Python built into macOS verify against a bundle file Apple has not updated, and gives a workaround.
  2. Rebuild container images once their base images pick up the change, and check the layer that actually verifies certificates. Cloudflare’s guidance puts it this way: “Updating the SDK alone may not change the underlying policy.”
  3. Replace certificates that chain to emSign ECC Root CA - G3 before Chrome’s removal on October 27, and force the renewal if your ACME client would otherwise wait for its normal window.
  4. Do not clear the resulting errors by turning verification off. Cloudflare says it is “important to not resolve these errors by disabling verification.” Until a distribution ships a package, Jackson’s page lists per-distribution commands that distrust the two roots; it says they are not recommended for ordinary users, and removing a root also breaks legitimate certificates under it, as Chrome notes for its own removal.

What is still open

eMudhra has not published a confirmed root cause, and commenters on the bug are asking whether the keys were generated inside the HSM, as the company’s certification practice statement says, or loaded into it. The CA/Browser Forum’s Baseline Requirements, as they read today on GitHub, make a key generation script, an auditor’s witness or a video of the whole process, and an auditor’s report mandatory for root key pairs and for subordinate CAs that someone else operates. For key pairs of the root operator or its affiliates, the script and the witness or video are only a SHOULD in section 6.1.1.1, while the requirement to “maintain effective controls to provide reasonable assurance that the Private Key was generated and protected in conformance with the procedures described in its Certificate Policy and/or Certification Practice Statement” applies in all cases. The certificates name eMudhra BV and eMudhra Inc. in their subject fields. Whether they count as affiliates, and so which tier applied on April 30, 2025, is not settled in the public record we read, and we did not check the text in force on that date. A commenter on the bug has asked eMudhra for the script, the ceremony report and the witness or video record.

Exploitation is also unresolved. Jackson’s page says: “We do not know if attackers exploited the flawed key generation to target these clients.” None of the sources we read reports a forged certificate in use. Chrome says no TLS certificates chaining to the six TLS intermediates were logged to Certificate Transparency before its block, which protects clients that enforce CT and says nothing about clients that do not. The keys were recoverable from the day the certificates existed. A second WebPKI incident two weeks earlier, covered in our post on the .gh, .sl and .as hijacks, ended the same way for Chrome: the fraudulent certificates were blocked through its CRLSet, a fast path that browsers have and many other clients lack.

Sources and method

We read Mozilla’s incident bug 2083449 and the earlier bug 1970728 through Bugzilla’s REST API, Chrome’s security blog post, eMudhra’s status page, Jackson’s incident site with its certificate list, proof files and patched-software table, Cloudflare’s and Helme’s posts, The Hacker News and The Register for context, Stanford’s IT page on its move to eMudhra’s certificate service, Go’s release history and the CA/Browser Forum’s Baseline Requirements on GitHub. Mozilla’s own security blog post answered scripted requests with HTTP 403, so Mozilla’s account is cited through the bug and Jackson’s site. We verified the proof signatures and key sizes ourselves from the public certificates, fetched the live CRLs named in the certificates, and ran the client tests above between 10:14 and 10:19 UTC on October 22 against Jackson’s public test hosts. The tests cover one machine, so other systems may differ. We did not request or build any forged certificate and did not publish key values beyond the one Helme reported. “Wayne” is the name used in the public record, and we did not look for more about the researcher.

Tags:

Certificate TransparencyCryptographyeMudhraMozillaPKITLS

Share

Blue velvet rope strung between chrome posts across the entrance of a glass storefront, a picture of an allow-list at the door
Previous Post

How to Fix CORS Errors in FastAPI Without Letting Every Website Read Your Users’ Data

A stone gatehouse with a thatched roof and a white toll gate across a road in Somerset, England
Next Post

OpenAI’s Usage Policy Rewrite Turns Model Gateways Into an Approval Request and Fences Off Training Signals, but the Announcement Barely Mentions the Training Rules

No Comment! Be the first one.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Latest
27 Oct
How to Find a Slow Query in PostgreSQL 18 With pg_stat_statements, Read Its EXPLAIN ANALYZE Plan, and Fix It With the Right Index
27 Oct
Two Labs’ Claimed Refutations of the Exponential Time Hypothesis Turn Verification Into a Statement-Reading Problem, and Their Lean Theorems Promise Only That a Constant Exists
Trending
October 27, 2026
How to Find a Slow Query in PostgreSQL 18 With pg_stat_statements, Read Its EXPLAIN ANALYZE Plan, and Fix It With the Right Index
October 27, 2026
Two Labs’ Claimed Refutations of the Exponential Time Hypothesis Turn Verification Into a Statement-Reading Problem, and Their Lean Theorems Promise Only That a Constant Exists
October 27, 2026
Tailscale Merged Fixes for Most of the 11 “Tailworm” Findings Before Shipping a Release, and the Forwarding Switch It Recommends Already Exists in the Shipped Client
October 27, 2026
How to Stop Decompression Bombs in Python With Hard Output Limits for gzip, Brotli, zstd, ZIP, and tar.gz
October 27, 2026
Anthropic’s S-1 Puts Safety Audits Inside the “Closing the Loop” Cycle It Warns About, and Says Its Evaluations Could Overstate Safety
October 27, 2026
Cloudflare Says Its GLM-5.3 Model Returned Other Customers’ Data in 155 Responses, and a Public SGLang Bug Report Had Described the Same Path Since July

Related Posts

Rows of server racks in a data center representing network infrastructure targeted by botnets
News

C0XMO Botnet Shows Why Old Router Firmware Still Matters

June 7, 2026
Close-up of a USB flash drive, representing physical data-theft risk in office security incidents
News

Fake IT Support Is Now Walking Through the Front Door

June 7, 2026
A phone security app on a smartphone resting on a laptop keyboard.
News

Everest Forms Pro Flaw Is Being Exploited to Create Rogue WordPress Admins

June 7, 2026
A phone secured by a padlock, illustrating AI data-leak containment and security controls.
News

OpenAI’s Lockdown Mode Is a Data-Leak Brake, Not a Prompt-Injection Cure

June 8, 2026
SXZ.io SXZ.io
  • [email protected]

Categories

Articles
Learning Hub
News

All Rights Reserved by SXZ.io ©2026