Skip to content

DH KeyPairGenerator rejects l == bitLength(p) since 1.85, which breaks Oracle JDBC Native Network Encryption #2554

Open

Description

@dharmashivam-cb

Since 1.85, the BC provider's DH KeyPairGenerator rejects a DHParameterSpec whose private value length l equals the bit length of p. 1.84 accepted it, and the JDK's SunJCE provider still does. This breaks Oracle JDBC connections that use Oracle Native Network Encryption (NNE) in applications that register BC ahead of SunJCE.

The change is in 85b85e8 ("DH updates", 2026-06-19), which changed the check in DHParameters from l > p.bitLength() to l >= p.bitLength(). It's still on main and in 1.86, and I couldn't find it in the release notes.

Minimal reproduction (JDK 21, no Oracle needed):

import java.security.KeyPairGenerator;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class DhFullLengthL {
    public static void main(String[] args) throws Exception {
        // Any 2048-bit DH group; here the JDK's built-in one.
        KeyPairGenerator sun = KeyPairGenerator.getInstance("DH", "SunJCE");
        sun.initialize(2048);
        DHParameterSpec group = ((DHPublicKey) sun.generateKeyPair().getPublic()).getParams();

        // Private value length equal to the prime size, as Oracle's JDBC driver passes it.
        DHParameterSpec spec = new DHParameterSpec(group.getP(), group.getG(), group.getP().bitLength());

        KeyPairGenerator jdk = KeyPairGenerator.getInstance("DH", "SunJCE");
        jdk.initialize(spec);
        jdk.generateKeyPair();
        System.out.println("SunJCE: OK");

        KeyPairGenerator bc = KeyPairGenerator.getInstance("DH", new BouncyCastleProvider());
        bc.initialize(spec);
        bc.generateKeyPair();
        System.out.println("BC: OK");
    }
}

Result on OpenJDK 21.0.13:

bcprov-jdk18on 1.84:  SunJCE: OK, BC: OK
bcprov-jdk18on 1.85 and 1.86:  SunJCE: OK, then
java.security.InvalidAlgorithmParameterException: when l value specified, it must be less than bitlength(p)
        at org.bouncycastle.jcajce.provider.asymmetric.dh.KeyPairGeneratorSpi.initialize(Unknown Source)

How Oracle hits it: in ojdbc11 21.x (tested with 21.20.0.0 and 21.21.0.0), oracle.net.useJCEAPI defaults to true, so the driver's NNE key exchange calls KeyPairGenerator.getInstance("DiffieHellman") with no provider and initializes it with new DHParameterSpec(p, g, keyLength), using the prime and key length the database server sends. The server sends a 2048-bit prime and a key length equal to the prime size, so with BC at provider position 1 the connection fails with the exception above. We see it with Oracle Database 19c and reproduced it with 21c, with SQLNET.ENCRYPTION_SERVER = required.

Questions:

  1. Is rejecting l == bitLength(p) intended? If the goal is to keep the generated private value below p, could the JCA KeyPairGeneratorSpi accept this case the way SunJCE does, for compatibility?
  2. If the strict check stays, could it go in the release notes? As far as I can see there's no property to relax it; org.bouncycastle.dh.allow_unsafe_p_value only applies to the m check.

Activity

  1. self-assigned this
    on Nov 5, 2026
  2. dghgit commented on Nov 5, 2026

    @dghgit
    Contributor

    Hmmm. We might have overdone it. Try the release candidate in https://www.bouncycastle.org/betas and let me know how it goes.

  3. dharmashivam-cb commented on Nov 5, 2026

    @dharmashivam-cb
    Author

    @dghgit Thanks, the 1.87 RC fixes it: the repro passes again, and Oracle NNE connection works with the RC jars.

  4. dghgit commented on Nov 5, 2026

    @dghgit
    Contributor

    We found a small gap in the update. I've dealt with that and confirmed there doesn't appear to be a regression but if you would retry the latest now I can make sure what winds up on Maven will work for you:

    sha256sum d70aad6c26d6838a35acd5fd8ec7ef1a2f6c5b7a181fe45d1aea8210e4cc0f28 bcprov-jdk18on-1.87.jar

    Up on https://www.bouncycastle.org/betas

  5. dharmashivam-cb commented on Nov 6, 2026

    @dharmashivam-cb
    Author

    @dghgit the updated RC (bcprov sha256 d70aad6c...0f28) works for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions