CVE-2026-91403: How eMudhra’s Weak CA Keys Broke Java TLS Trust

The CyberSec Guru

If you like this post, then please share it:

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Why your support matters: Zero paywalls: Keep the main content 100% free for learners worldwide.

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

In October 2026, researchers found that eight intermediate certificate authorities run by eMudhra, an Indian digital trust services provider, were protected by private keys with at most eight bits of entropy. One of the keys was the integer 4. Recovering any of them took a laptop and a few milliseconds.

The result is CVE-2026-91403, a critical flaw in the Java Secure Socket Extension (JSSE) that Oracle rated 9.1 on CVSS 3.1. Oracle issued an emergency out-of-band security alert for Java SE and GraalVM, browser root programs moved to block the keys, and eMudhra later left the global SSL/TLS certificate business. The weak keys had been trusted for seventeen months before anyone noticed.

What is CVE-2026-91403?

CVE-2026-91403 is a critical vulnerability in how Java runtimes trust certificates chaining to the compromised eMudhra intermediates. Anyone who holds the private key of a trusted intermediate CA can mint certificates that pass validation. Here, anyone could derive the keys.

Browsers can push emergency blocklists through mechanisms like CRLSet and OneCRL within hours. Java works differently. Applications usually rely on a static, bundled trust store, typically the cacerts file in $JAVA_HOME/lib/security/. Backend microservices, CI/CD agents and enterprise integration buses all use it for outbound HTTPS, and none of them update it in the background. That is why the Java side of this incident is so much harder to close.

How eMudhra’s private keys ended up with only 8 bits of entropy

The affected intermediates used the NIST P-384 curve, which is designed to provide 192 bits of security strength. A correctly generated P-384 private key is a secret integer chosen at random from a range approaching 2^384, a space of roughly 116 digits. Recovering such a key from its public point is computationally infeasible.

The eMudhra keys were nowhere near that range. The private scalars for eight intermediate CAs were all below 256: 4, 56, 66, 115, 155, 156, 230 and 237. To crack one, an attacker iterates through at most 256 candidates, multiplies each by the curve’s generator point, and compares the result with the public key in the X.509 certificate. No lattice reduction or side channel is needed.

An independent researcher using the pseudonym “Wayne” found the keys on October 17, 2026, while running test data from the Common CA Database (CCADB) against the curve parameters. To prove control, Wayne used the compromised keys to sign the message “We have a problem here” and sent the attestations to Mozilla, Google, Apple and Microsoft. Mozilla’s cryptography engineers recovered the same keys within hours, without knowing Wayne’s method.

How the key generation went wrong

The weak keys came from a procedural and scripting failure, not from the math. eMudhra created the affected intermediates during a Key Generation Ceremony (KGC) on April 30, 2025, using FIPS 140-2 Level 3 certified hardware security modules (HSMs). An HSM is a tamper-resistant device built to generate and store keys so that private keys never exist in plaintext outside it.

According to eMudhra’s incident reports on Mozilla’s Bugzilla, an approved deviation from the standard KGC script was introduced to test a wrap/unwrap procedure. Key wrapping encrypts a private key under a separate transport key so it can be exported from one HSM and imported into another. A flaw in the custom KGC code created a second, very weak set of key pairs on the HSM alongside the intended strong ones. The labels for the two sets were so similar that the script picked the weak keys when it generated the Certificate Signing Requests (CSRs).

The eMudhra root CA signed those CSRs, which put the weak keys into the trusted WebPKI hierarchy. The CSRs also went to Sectigo for cross-signing, so the same compromised public keys ended up in a second trust hierarchy as well.

📬 Stay Ahead of Cyber Threats

Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.

Subscribe to the Newsletter →

Audits are part of the reason this survived. An auditor can confirm that a certified HSM is present, but a custom script that silently substitutes a trivial key during a non-standard procedure is much harder to see.

The June 2025 CRL anomaly nobody followed up

The ecosystem got a warning seventeen months before the public disclosure and misdiagnosed it. In June 2025, Mozilla engineers tracking Bug 1970728 noticed that Certificate Revocation Lists (CRLs) published by the new eMudhra intermediates were failing signature validation. A CRL is a signed list of certificates a CA has revoked before their expiry date.

The post-mortem explains why. The initial CRLs had been signed with the intended strong keys, but the issued certificates contained the public halves of the weak keys. The signatures could not match. eMudhra’s engineers investigated, found the second key set on the HSM that did match the certificates, and used it to re-sign the CRLs. Validation passed and the bug was closed.

Nobody asked why two key pairs existed for the same CA, or why the first pair failed against the issued certificates. Those two questions would have exposed the problem.

Why JSSE accepts forged certificates

When a Java application opens an HTTPS connection, JSSE validates the server’s certificate path. It checks signatures, traces the chain of intermediates back to a trusted anchor, and verifies validity periods and hostname constraints. An attacker who knows the intermediate CA’s private key can forge a leaf certificate with a mathematically perfect signature, so JSSE validates it exactly as designed. It has no way to judge the entropy or provenance of the key behind a signature.

An attacker who can get into the network path, through DNS poisoning, BGP hijacking or a compromised corporate proxy, can present a forged certificate for an internal API signed by the compromised intermediate. An unpatched Java application accepts it, completes the handshake, and sends database credentials, API tokens and personal data to the attacker.

The encryption itself still works. What fails is authentication: the client encrypts its traffic to an attacker it believes is the real server.

Java eMudhra TLS Attack Flow
Java eMudhra TLS Attack Flow

How JSSE trust decisions work and why blocked.certs falls short

To see why the manual mitigation is fragile, it helps to know how JSSE decides. When an application uses HttpsURLConnection or an SSLContext, JSSE hands certificate path validation to an X509TrustManager. The default implementation, X509TrustManagerImpl, builds a path from the server’s leaf certificate to a trusted anchor in the cacerts keystore. Along the way it checks signatures, basic constraints and key usage.

The blocked.certs file overrides that logic. It replaced the older blacklisted.certs mechanism in later JDK versions and holds Base64-encoded SHA-256 fingerprints. The JVM loads it at startup. For each certificate in the chain, the trust manager hashes the DER encoding and compares it with the list. A match throws a CertificateException and ends the handshake before any application data moves.

Here is the weakness. If Oracle’s emergency blocklist covers only the fingerprints of the original eMudhra intermediates, those chains are blocked. The Sectigo cross-signed variants contain the same compromised public key (the same Subject Public Key Info, or SPKI) but have a different DER encoding, serial number and issuer, so their fingerprints differ. They chain to Sectigo’s widely trusted AAA Certificate Services root, and JSSE does not compare SPKI hashes against a blocklist unless it is configured or patched to do so. An attacker presenting the Sectigo chain walks straight past a fingerprint blocklist.

Revocation checking does not rescue you either. Many enterprise Java environments disable OCSP and CRL checks by default to avoid latency and network dependencies.

The reliable fixes distrust the key itself. Google’s approach blocks by SPKI hash, which rejects any chain that relies on the compromised key no matter which root vouches for it. The fixed Java runtimes do the equivalent: Oracle and OpenJDK updated the JSSE trust logic to distrust the underlying SPKI hashes or the parent emSign ECC Root CA - G3 entirely. A manual blocked.certs entry is only as good as its coverage of every cross-signed variant.

Certificate Transparency won’t tell you whether you were hit

Certificate Transparency (CT) requires CAs to log every certificate they issue to public, append-only Merkle trees, so domain owners and monitors can spot unauthorized issuance. After the disclosure, analysts noted with relief that no fraudulent end-entity certificates chaining to the compromised intermediates had been logged before the takedown.

That tells you less than it seems to. CT detects mis-issuance after the fact and does not prevent it. An attacker holding an intermediate’s private key does not have to log anything, and Java’s JSSE does not enforce CT during standard TLS handshakes. A man-in-the-middle can generate a forged certificate on the fly, sign it with the compromised key and present it to the victim without it ever reaching a log. Browsers enforce CT through Expect-CT headers or built-in log requirements, but a backend Java service has no such check.

An empty CT log is therefore not evidence of safe traffic. The keys were exposed for the whole seventeen months between the April 2025 ceremony and the October 2026 disclosure, so anyone could have used unlogged certificates for targeted interception or lateral movement. Assume that any TLS connection made by an unpatched Java runtime in that window could have been intercepted, and rotate every API key, database credential and session token that crossed those connections.

How to fix CVE-2026-91403 in Java

Oracle shipped its fix as an emergency out-of-band alert instead of waiting for the quarterly Critical Patch Update. The affected Oracle Java SE versions are 8u511, 11.0.33, 17.0.21, 21.0.13, 25.0.5 and 27.0.1, along with the corresponding Oracle GraalVM releases.

Patching is rarely a single package-manager command in an enterprise. Java runtimes sit inside application containers, vendor appliances and legacy build systems. A workable sequence:

  1. Inventory every Java runtime in your infrastructure, paying attention to the JAVA_HOME values used by production services.
  2. Apply the vendor-fixed JDK wherever you can. This is the definitive remediation.
  3. If you cannot upgrade immediately, add the SPKI hashes or fingerprints from Oracle’s advisory to blocked.certs (blacklisted.certs on JDK 8). Append to the file so you keep any custom entries for internal enterprise CAs.
  4. Do not rely on updating the operating system’s ca-certificates package. A standalone JDK uses its own bundled cacerts and gets no protection from it.
  5. Restart the JVM so it loads the new trust material.
  6. Test in staging by connecting to a server that presents a chain through the compromised eMudhra intermediates. A patched JSSE ends the handshake with a certificate validation error. A vulnerable one completes the connection without complaint.

What the eMudhra collapse says about the WebPKI

The WebPKI runs on delegated trust. Browser vendors and OS maintainers grant root privileges to CAs based on audits, compliance with the CA/Browser Forum Baseline Requirements and a promise of careful operations. eMudhra had FIPS 140-2 Level 3 hardware and a formal key ceremony, and a custom script plus one procedural deviation bypassed all of it.

A CA generated a private key with the value four, issued certificates with it, missed the error when its own CRLs failed to validate, and left the keys exposed for over a year. That points to a lack of continuous, automated cryptographic verification inside the CA’s own infrastructure.

Under scrutiny from the Mozilla and Chrome root programs, and facing possible distrust, eMudhra’s parent company announced that it would withdraw voluntarily from the global SSL/TLS certificate business. It cited rising compliance costs and the disproportionate scrutiny the incident brought. Its remaining 30,000 enterprise customers are being moved to other hierarchies, and the company will focus on its domestic digital signature markets.

The broader lesson is that key strength depends on the whole lifecycle: the HSM’s entropy source, the ceremony script, and the ongoing monitoring of issued certificates. A successful handshake shows the math was run correctly. It says nothing about whether the people who set the parameters got them right.

Key takeaways for Java and security teams

CVE-2026-91403 was caused by defensive failures: a flawed ceremony script, a misread warning and a trust model that cannot check where a key came from. For Java shops, the emergency patches and blocklist updates are the immediate fix. Beyond that, treat your trust stores as active security boundaries. Audit them, update them on a schedule, and manage them with the same rigor as application code and firewall rules.

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Your contribution powers free tutorials, hands-on labs, and security resources.

Why your support matters:
  • Writeup Access: Get complete writeup access within 12 hours
  • Zero paywalls: Keep the main content 100% free for learners worldwide

Perks for one-time supporters:
☕️ $5: Shoutout in Buy Me a Coffee
🛡️ $8: Fast-track Access to Live Webinars
💻 $10: Vote on future tutorial topics + exclusive AMA access

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

If you like this post, then please share it:

News

Discover more from The CyberSec Guru

Subscribe to get the latest posts sent to your email!

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from The CyberSec Guru

Subscribe now to keep reading and get access to the full archive.

Continue reading