Diffie-Hellman 2048-bit MODP now supported by JDK 8

Diffie-Hellman key pair generator provided by Sun’s JCE provider had been rejecting prime number modulus whose size is more than 1024 bits. In JDK 7 and earlier, the size must be a multiple of 64 that ranges from 512 and 1024 inclusive.

JDK 8 was released recently. The upper limit was lifted up to 2048. Below is a description about this change quoted from Security Enhancement in JDK 8.

  • Enhanced Support for NSA Suite B Cryptography: This includes the following:

    • OID registration for NSA Suite B cryptography algorithms
    • SUN provider: Support for 2048-bit DSA key pair generation and additional signature algorithms for 2048-bit DSA keys such as SHA224withDSA and SHA256withDSA.
    • SunJCE provider: Lifting of the keysize restriction from 1024 to 2048 for Diffie-Hellman (DH).

    See Oracle Providers Documentation, Standard Algorithm Name Documentation, and RFE 7044060.

The request for enhancement was raised about 7 years ago at latest, by JDK-6521495. Having been ignored for a long time, and finally it was fixed by JDK-7044060.

I have just done a very small test.

import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyPairGenerator;
import javax.crypto.spec.DHParameterSpec;
import org.junit.Test;

public class DiffieHellmanKeyPairGeneratorTest {
    
    private static final String modp1024 = (
        "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
        "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
        "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
        "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
        "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381" +
        "FFFFFFFF FFFFFFFF")
        .replaceAll("\\s", "");
    
    private static final String modp1536 = (
        "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
        "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
        "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
        "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
        "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
        "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
        "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
        "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF")
        .replaceAll("\\s", "");
    
    private static final String modp2048 = (
        "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
        "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
        "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
        "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
        "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
        "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
        "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
        "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
        "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
        "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
        "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF")
        .replaceAll("\\s", "");
    
    private void testWith(BigInteger p, BigInteger g)
            throws GeneralSecurityException {
        KeyPairGenerator gen =
            KeyPairGenerator.getInstance("DiffieHellman");
        gen.initialize(new DHParameterSpec(p, g));
    }
    
    @Test
    public void testWithMODP1024()
            throws GeneralSecurityException {
        BigInteger p = new BigInteger(modp1024, 16);
        BigInteger g = BigInteger.valueOf(2L);
        testWith(p, g);
    }
    
    @Test
    public void testWithMODP1536()
            throws GeneralSecurityException {
        BigInteger p = new BigInteger(modp1536, 16);
        BigInteger g = BigInteger.valueOf(2L);
        testWith(p, g);
    }
    
    @Test
    public void testWithMODP2048()
            throws GeneralSecurityException {
        BigInteger p = new BigInteger(modp2048, 16);
        BigInteger g = BigInteger.valueOf(2L);
        testWith(p, g);
    }
    
}

The prime numbers used above are the ones defined in RFC 5996: Internet Key Exchange Protocol Version 2 (IKEv2) and RFC 3526: More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE). (I hope I have copied and pasted them precisely…)

The above test is failed if I use JDK 7u55. testWithMODP1536 and testWithMODP2048 encounter an exception thrown by Sun’s JCE provider as shown in the following excerpted stack trace.

Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
java.security.InvalidAlgorithmParameterException
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:658)
    at java.security.KeyPairGenerator.initialize(KeyPairGenerator.java:400)
    ...

It is passed successfully if I use JDK 8u5. It looks cool.

However, I have another feeling of a couple of questions emerging. Why is this enhancement not backported to JDK 7? Why does it not accept more than 2048 bits, e.g. 3072 bits, 4096 bits, and so on?

Advertisements

About tt4cs

I am a post-sale service engineer working in Tokyo for a Singapore-based software development company, which provides authentication and access management solutions for global and regional financial institutions in Asia-Pacific region.
This entry was posted in Cryptography, Java and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s