DEV Community

Cover image for eMudhra's eight-bit CA keys: how it happened and what to fix
Strongthium Labs
Strongthium Labs

Posted on Originally published at strongthium.com

eMudhra's eight-bit CA keys: how it happened and what to fix

In October 2026, eight intermediate certificate authorities run by the Indian company eMudhra turned out to have private keys that were small integers. The smallest was 4. Browsers blocked them within days. Servers, containers, build pipelines and devices that keep their own trust stores take longer to fix, and that work is still going on. This article covers what was found, how a key that small could get into a trusted certificate, how the company behind it was run, and what you can do on the machines you look after.

What was found

SOCRadar's FAQ on the compromise says an independent researcher who signs as "Wayne" reported the weakness on October 17, 2026, to Apple, Google, Microsoft, Mozilla and eMudhra. As proof, Wayne signed a message with each of the eight private keys. Six of the intermediates issue TLS certificates (DV, OV and EV, in G3B and G3C versions). The other two sign code. Sectigo had cross-signed all eight under its AAA Certificate Services root, so each key also appears in a certificate that Sectigo issued.

All eight came from a single key ceremony on April 30, 2025. That means the keys could have been recovered for about 17 months before anyone blocked them. According to SOCRadar, no malicious use had been confirmed as of October 21. Google reported that no TLS certificate chaining to the affected intermediates had been logged to Certificate Transparency (CT) before the block. That rules out attacks on clients that enforce CT. It tells you nothing about clients that don't check CT.

Cloudflare's write-up says the company learned of the compromise on October 19 and patched its own services before public disclosure. Its review found no active exploitation on Cloudflare services. It also stresses that this is a failure of certificate-based authentication, not a weakness in TLS encryption.

How a key can be the number 4

On a curve like P-384, a private key is just an integer d between 1 and the order of the curve's base point, which is about 384 bits long. The public key is the base point added to itself d times. Every integer in that range is a valid key. The curve math does not reject d = 4, and the certificate format has no field that would show it. As SOCRadar notes, the affected certificates "look structurally normal". You only see the flaw when you test the private key against the public key.

All the security comes from choosing d at random from that huge range, so that the only way back from the public key is a search no one can finish. A key below 256 turns that search into at most 255 tries. Anyone with the certificate can run it:

from cryptography import x509
from cryptography.hazmat.primitives.asymmetric import ec

cert = x509.load_pem_x509_certificate(open("intermediate.pem", "rb").read())
target = cert.public_key().public_numbers()
for d in range(1, 256):
    if ec.derive_private_key(d, ec.SECP384R1()).public_key().public_numbers() == target:
        print("private key is", d)
        break
Enter fullscreen mode Exit fullscreen mode

The Wikipedia article on eMudhra lists the eight keys as 4, 56, 66, 115, 155, 156, 230 and 237. It describes them as having between 3 and 8 bits of entropy. SOCRadar rounds this to "roughly eight bits". The two figures don't conflict: 4 needs three bits and 237 needs eight. Wikipedia also reports that security researcher Scott Helme recovered several keys in under a second.

That explains why the keys could be broken. It doesn't explain how they got into certificates. The sources describe eMudhra's preliminary explanation at different levels of detail:

  • SOCRadar says eMudhra blamed a flaw in its key-generation ceremony script. The script created a second, weak key pair on the hardware security module. Because the two pairs had similar labels, the weak pair was used for the certificate signing requests. eMudhra also cites human error at several steps.
  • Wikipedia says a flaw in a "key wrap/unwrap" step produced a second, weak set of keys, and staff used them by mistake.

Both say the root cause was still being investigated as of October 21. eMudhra has said it will re-check every key ceremony it has run.

There was an earlier warning that was misread. SOCRadar notes that in June 2025, Mozilla's bug tracker recorded invalid certificate revocation list (CRL) signatures from the same six TLS intermediates. eMudhra said at the time that a manual process had referenced the wrong CA key, published corrected CRLs, and the bug was closed. Its 2026 account links those invalid CRLs to the same key mismatch. Put simply, signatures that didn't verify against the published certificates were treated as a paperwork error, not as a sign that the certificates held the wrong keys.

A key ceremony room where a technician holds a tiny, flimsy key while an identical-looking large, sturdy key sits unused in an open hardware module

How the business around it was run

Wikipedia's account shows a company that grew mainly through India's regulated digital signature market. eMudhra was founded in 2008 as a subsidiary of 3i Infotech, licensed by India's Controller of Certifying Authorities, and listed on Indian stock exchanges in 2022. It launched its emSign certificate authority in 2018 after a WebTrust audit. Mozilla accepted four emSign roots, including emSign ECC Root CA – G3, in December 2018. Browsers had been wary of Indian CAs since the National Informatics Centre's CA issued unauthorized certificates in 2014. That made eMudhra the only Indian root CA trusted worldwide.

Publicly trusted TLS was a small part of the business. Wikipedia cites ICRA's figures: enterprise software (secure access, PKI, paperless workflows and certificate lifecycle management) grew to about 80% of revenue by 2026, and international markets made up 64%. In an exchange filing, eMudhra said the affected business accounted for about 1% of revenue. It also said its Indian digital signature and eSign services ran on separate systems.

The effects were not small. eMudhra's shares fell 20% on October 21 and 40% over the two days after disclosure. Indian government sites, including the Aadhaar issuer UIDAI and the income tax portal, used eMudhra certificates. Wikipedia reports that some sites, such as FSSAI, became unreachable after the revocations. CERT-In issued an advisory. The Ministry of Electronics and Information Technology set up a team to investigate and said the regulated signature services were not affected. On October 22, eMudhra announced it would leave the global SSL/TLS certificate business. Wikipedia reports that the company also called the social media scrutiny out of proportion to the division's place in the company.

At the time of writing, eMudhra's own homepage still lists "CLM & SSL/TLS Certificates" among its featured products. Its newsroom shows the October 22 exit notice and a later item saying ICRA kept the company's ratings after the incident. One way to read the record is that 1% of revenue still meant a globally trusted root, about 30,000 customer certificates, and many government websites. Readers can judge how well the controls around that business matched what it carried.

Where the risk remains

Browsers have been dealt with. SOCRadar's timeline shows Chrome blocking the intermediates through a CRLSet update and Firefox through OneCRL, both on October 17, then Apple on October 19 and Microsoft on October 20. Mozilla removed emSign ECC Root CA – G3 from NSS on October 20. Chrome's removal of that root is expected to reach all devices by October 27. Cloudflare's post says browser vendors could fix this "with a flip of a switch" because they have one application to update and fast revocation channels.

Servers have no such channel. API clients, backend services, containers, CI/CD runners and embedded devices often trust a bundled CA store, skip revocation checks and ignore CT. SOCRadar reports that in Scott Helme's tests, curl, Python and Node.js on Linux and macOS accepted a forged certificate issued under one of the compromised intermediates. Go programs only get the block after being rebuilt with a patched toolchain. The two code-signing CAs are also a concern on Windows systems that skip revocation checks. eMudhra says neither was ever used, but code-signing certificates aren't logged to CT, so there is no public record either way. Wikipedia also notes that mitmproxy added an option to sign with the leaked keys, so forging certificates now takes no special skill.

A server rack in a dim data center where most machines show a closed padlock, while a few older machines and containers in the corner still show an open one

Cleaning it out of your servers

Update, rebuild, test

The order of work is the same in all the sources:

  1. Update every trust store. That means the OS ca-certificates package and language-level bundles. SOCRadar lists fixed versions, including Python certifi 2026.10.19, Node.js 22.23.4, 24.22.1 and 26.12.1, and webpki-roots 1.0.10. It also notes that Bun and FreeBSD fixes were still pending on October 21.
  2. Rebuild, don't just patch. Recompile Go services with Go 1.27.3 or 1.26.10. Rebuild container images from patched base images. Cloudflare adds that you should check whether each application needs a reload, restart or redeploy before the change takes effect.
  3. Look beneath the SDK. Cloudflare points out that an API client may hand certificate checks to an HTTP library, the language runtime, the OS or a custom trust configuration. Updating the SDK alone may change nothing.
  4. Review what you trust as a server. If your origin or proxy verifies client certificates with mutual TLS, check the CA list it uses. Also find any of your own sites that still serve G3-chained certificates.
  5. Test through the real path. The disclosure site serves chains through the compromised intermediates. A certificate error is the result you want:
curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/
Enter fullscreen mode Exit fullscreen mode

As Cloudflare notes, a passing curl test says nothing about an application that uses a different verifier.

Warning
After patching, you may see new certificate errors in logs and dashboards. Do not fix them by turning off verification. As Cloudflare puts it, that "would remove the authentication protection these updates are intended to restore." Replace the certificate or the chain instead.

Distrusting the certificates by hand with emudhra-patch

Some hosts can't take a package update yet, and some you want closed before the next maintenance window. For these, Strongthium Labs publishes emudhra-security-patch, an MIT-licensed, single-file tool for Windows and Linux. It finds the eight G3B and G3C intermediates and their emSign G3 roots in the system trust stores and distrusts them:

emudhra-patch scan       # report where each certificate is; changes nothing
emudhra-patch revoke     # distrust them (root on Linux, administrator on Windows)
emudhra-patch restore    # undo revoke from the backup it made
Enter fullscreen mode Exit fullscreen mode

The README describes how it works. scan exits with code 2 if anything on the list is still trusted, so you can run it as a monitoring check. On Windows, it removes the certificates from the trusted stores and adds them to the machine's Disallowed store. That also blocks a root that Windows Update hasn't fetched yet. On Debian and Ubuntu, it deselects the root in /etc/ca-certificates.conf. On Fedora, RHEL, Arch and openSUSE, it uses the p11-kit blocklist. Every change is backed up and listed in a manifest, and restore undoes the changes in reverse order. The certificate list is a plain file, badcerts.txt, matched by SHA-256 fingerprint.

Some things to know before you run it:

  • The revoke command distrusts certificates on your machine only. Actual revocation was done by eMudhra and Sectigo.
  • Distrusting emSign ECC Root CA – G3 drops everything eMudhra issued under that root, which matches Mozilla's decision. To keep it, comment out its line in badcerts.txt.
  • The tool also distrusts any certificate that shares a key with a listed one, and that certificate's issuers up to the root. SOCRadar warns that removing Sectigo's AAA Certificate Services can break legitimate connections. Read the scan output before you run revoke.
  • It does not touch Firefox or Thunderbird stores, Java cacerts unless built from the system store, NSS databases in ~/.pki/nssdb, containers, or runtimes that ship their own bundle. Those still need their own updates.
  • If you download a release build, check it against the published SHA256SUMS. You can also build it yourself with the .NET 10 SDK.

What to take from it

The weakness itself was simple. The certificates were well formed and the ceremony was recorded. Still, a mixed-up key label and a misread CRL error led to six globally trusted TLS CAs, plus two code-signing CAs, whose keys anyone could guess. For people who run servers, the longer-lasting lesson is the one Cloudflare draws: a trust store can't be a static list that changes only when a package updates. Find out which verifier each of your services actually uses, make sure you can push a distrust quickly, and keep scan-style checks running until every host comes back clean.

Sources


First published on Strongthium Lab Notes.

Top comments (0)