eMudhra CA compromise check
The private keys of eight eMudhra intermediate CAs can be calculated from their public certificates. Anyone holding one can issue a certificate for any website. Find out whether your sites, servers and clients are affected, and what to change before Chrome removes the root on 27 Oct 2026.
Check your exposure
Four questions: did a CA issue for your names, is a chain affected, does this browser trust it, and do your systems trust it?
Search Certificate Transparency for your domain
We look up every unexpired certificate logged for the name in the public CT logs, then check its issuer against the 8 compromised CAs and the whole emSign ECC Root CA - G3 hierarchy. We never connect to your site. CT data is public, so you don't need to own the domain.
Capture the chain a host actually serves
This is the definitive check for a server, load balancer, appliance or API endpoint. Run one of these against it, or export the certificate from your server, browser or certificate store.
openssl s_client -connect www.example.com:443 -servername www.example.com -showcerts </dev/null 2>/dev/null | sed -n '/BEGIN CERT/,/END CERT/p'
Uses .NET to read the chain the server sends. It doesn't validate it, so it also works when the chain is already blocked.
$h='www.example.com'; $t=New-Object Net.Sockets.TcpClient($h,443); $s=New-Object Net.Security.SslStream($t.GetStream(),$false,{param($a,$c,$ch,$e) $global:raw=@(,$c.GetRawCertData()) + @($ch.ChainElements | select -Skip 1 | % { ,$_.Certificate.RawData }); $true}); $s.AuthenticateAsClient($h); $global:raw | % { "-----BEGIN CERTIFICATE-----`n"+[Convert]::ToBase64String($_,'InsertLineBreaks')+"`n-----END CERTIFICATE-----" } | Set-Clipboard; $t.Close()Drop or choose a .pem, .crt or .cer file (PEM or DER) below. On Windows, export from certlm.msc as Base-64 encoded X.509 or DER; both work.
Paste the certificate or chain
Every PEM block is read: a leaf, a full chain, or a whole bundle. Parsing and fingerprinting happen in your browser.
.pem / .crt / .cer file here
Does this browser still trust the compromised CAs?
Your browser tries to load 14 test sites, each serving a certificate issued by one of the compromised intermediates, via the emSign root and via the Sectigo cross-sign. A connection that fails is the result you want. Two sites use certificates that were never logged to CT, which catches clients that trust the CA but enforce CT.
Collect evidence on the machine
Read-only scripts. They test each CA bundle against the compromised chains, read runtime and package versions, and look for eMudhra certificates the machine serves. They change nothing and send nothing anywhere unless you add --online / -Online; you copy the output yourself.
Tests the system bundle, Python certifi, Node.js, Java cacerts, Git and SSL_CERT_FILE-style overrides with openssl verify. It also scans nginx, Apache, HAProxy, Caddy and Let's Encrypt folders for eMudhra certificates. Run it with sudo so it can read the certificate folders. Add --path DIR for other locations.
Add --deep to find vulnerable apps, not just the system. It sweeps /opt, /srv, /usr/local, /usr/lib, /usr/share, /var/lib, /home, /root and /Applications. There it tests every CA bundle an app ships (every Python certifi and virtual environment included) and every Java runtime's cacerts. It also lists Electron apps and Go programs with the Go version each was built with. It only reads files and never runs what it finds; expect a few minutes.
curl -fsSLO https://scan.theadminstack.com/emudhra/scripts/emudhra-check.sh less emudhra-check.sh # review it sudo bash emudhra-check.sh --deep # drop --deep for a quick scan; add --online to test curl
Asks Windows to build a chain for three of the compromised CAs: TLS via the emSign root, TLS via the Sectigo cross-sign, and code signing. It counts the 16 certificates in Untrusted Certificates and reads when the automatic root list last synced. It then checks bundles that bypass Windows (Python certifi, Node.js, Java, Git with OpenSSL), the machine and IIS certificate stores, and, with -CodeSigningScan, Authenticode signatures. Run it from an elevated PowerShell.
Add -Deep to find vulnerable apps. It sweeps Program Files, Program Files (x86), ProgramData, C:\Python* and per-user installs (AppData\Local\Programs, AppData\Local\pipx, AppData\Roaming\Python). There it tests every CA bundle an app ships and every Java runtime's cacerts, and lists Electron apps and Go programs with the Go version each was built with. Add folders with -Path. It reads file headers only; expect a few minutes.
$b = 'https://scan.theadminstack.com/emudhra' Invoke-WebRequest "$b/scripts/emudhra-check.ps1" -OutFile emudhra-check.ps1 Invoke-WebRequest "$b/certs/emudhra-compromised.p7b" -OutFile emudhra-compromised.p7b # test certificates notepad .\emudhra-check.ps1 # review it # from an elevated PowerShell (drop -Deep for a quick scan; add -Online or -CodeSigningScan 'C:\Program Files'): Unblock-File .\emudhra-check.ps1 Set-ExecutionPolicy -Scope Process RemoteSigned .\emudhra-check.ps1 -Deep | Set-Clipboard
Keep both files in the same folder. The .p7b holds the public certificates of the 16 compromised CAs; the script asks Windows to build a chain for three of them.
Base images carry their own CA bundle, frozen when the image was built. Run the Linux check inside each image you ship. The container needs bash and openssl; slim and distroless images may have neither, in which case rebuild on an updated base image.
curl -fsSLO https://scan.theadminstack.com/emudhra/scripts/emudhra-check.sh
for img in $(docker ps --format '{{.Image}}' | sort -u); do
docker run --rm --entrypoint bash -v "$PWD/emudhra-check.sh:/c.sh:ro" "$img" /c.sh --no-cert-scan 2>/dev/null \
| sed "s/^hostname=.*/hostname=$img/"
donePaste the output
Output from several machines can be pasted together: each one starts with [host].
eMudhra CA compromise exposure report
Fix it
Pick what you're fixing. Vendor updates come first: they remove the roots and block the keys in a tested way. The manual workarounds are for machines that can't update yet, and each has a cost.
Were you hit? Things to check
The keys could be calculated from April 2025 onwards, but Google reports no certificates chaining to these CAs were logged to CT before the 17 Oct 2026 block. The realistic risk is a forged certificate shown to a client that checks neither revocation nor CT. These checks look for that.
The certificates and the timeline
Every verdict is based on this data. Fingerprints were recomputed from the certificates and match Mozilla's incident report and the researchers' published list. Last updated 23 Oct 2026. Raw JSON · All 16 compromised certificates (PEM).
Compromised intermediate CAs
Each key was issued twice: once by eMudhra's own root and once as a Sectigo cross-sign under AAA Certificate Services. Both carry the same key.
| CA | Use | Issued by | SHA-256 | SHA-1 (Windows thumbprint) | Key (SPKI SHA-256) |
|---|
Also affected by the root removal
These CAs weren't compromised, but they chain to emSign ECC Root CA - G3. Certificates they issued stop working in Chrome on 27 Oct 2026 and already fail in Firefox and updated Linux CA bundles. eMudhra estimated about 30,000 certificates need migrating.
| CA | Use | Key (SPKI SHA-256) | crt.sh |
|---|
What the root programs did
| Store | Action |
|---|
Timeline
Fixed versions
| Component | Fixed in |
|---|