Safeguard
Vulnerability Analysis•

CVE-2026-59650: Critical DH Flaw in Bouncy Castle for Java

CVE-2026-59650 is a critical Bouncy Castle for Java flaw in MTI/A0 DH agreement. Upgrade to BC 1.85 or BC-LTS 2.73.12, and check if you use DHAgreement.

Safeguard Security Team
3 min read

CVE-2026-59650 is a critical (CVSS 9.1) flaw in Bouncy Castle for Java. The MTI/A0 Diffie-Hellman agreement raises an unvalidated peer value to the power of the local private key. Fixed in Bouncy Castle 1.85 and the LTS line 2.73.12. Upgrade, and rotate static DH keys if you used this class.

What's affected

  • Bouncy Castle for Java (bc-java) before 1.85. Fixed in 1.85.
  • Bouncy Castle for Java LTS before 2.73.12. Fixed in 2.73.12.
  • Platform: Java 8 and later, per the project wiki.
  • Weakness: CWE-20, improper input validation. CVSS 9.1 (critical), vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N.

The project wiki narrows the exposure. The issue is in the DHAgreement class, the MTI/A0 two-pass variant. The wiki says DHBasicAgreement is unaffected, because its single input passes through public key validation.

How to check if you're exposed

Find out which Bouncy Castle version your application resolves, then check whether your code uses the MTI/A0 class at all.

# Maven
mvn dependency:tree -Dincludes=org.bouncycastle

# Gradle
gradle dependencies | grep -i bouncycastle

# Does your own code use the affected class?
grep -rn "DHAgreement" src/

Remember transitive dependencies. Many libraries bundle or pull in Bouncy Castle, so check the full tree and any shaded jars. A free in-browser dependency scan at gold.safeguard.sh/scan lists the versions it finds.

What to do now

  1. Upgrade to Bouncy Castle 1.85, or to 2.73.12 if you are on the LTS line.
  2. Rebuild and redeploy every service that ships the library, including shaded copies inside fat jars.
  3. If your code used DHAgreement with a long-lived static private key, treat that key as possibly exposed and rotate it. The wiki describes a way a malicious peer can learn parts of the static key over repeated exchanges.
  4. Prefer an agreement scheme that validates every peer value. The wiki notes DHBasicAgreement is not affected.

Why it matters

The class took a raw number straight from the wire and used it as the base of a modular exponentiation with the local static private key. There was no range check and no subgroup membership check. That is a textbook input validation gap, filed as CWE-20.

The wiki explains why it matters: a peer that sends specially chosen small values can learn a little about the private key on each exchange, and enough exchanges can recover the whole key. That makes this a key recovery problem, not a crash. The record's KEV flag is false, and I found no statement of exploitation in the sources I read.

Try it yourself

Click through it at your own pace, or open it full screen.

Quick check

Does this affect every Bouncy Castle user?

The wiki ties the flaw to the MTI/A0 DHAgreement class. If your code never uses it, the practical exposure is small, but upgrading is still the clean fix.

Which versions fix it?

Bouncy Castle 1.85 and Bouncy Castle LTS 2.73.12, per the project wiki.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.