Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8255283

Leading zeros in Diffie-Hellman keys are ignored

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      We've encountered an issue with the Diffie-Hellman key exchange on 11.0.5 (but it's likely the same for other versions, too). Our application connects to a web server on an embedded device via regular https. The server has only Diffie-Hellman ciphers enabled. The handshake fails with the following error:

      Caused by: javax.net.ssl.SSLException: Could not generate DH keypair
        at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
        at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
        at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)
        at com.hp.www.oxpd.helpers.Utils.GetOXPdFileAtUri(Utils.java:82)
        at com.hp.www.oxpd.helpers.DiscoveryTreeTranslator.GetOXPdDiscoveryTree(DiscoveryTreeTranslator.java:75)
        ... 7 more
      Caused by: java.lang.RuntimeException: Could not generate DH keypair
        at java.base/sun.security.ssl.DHKeyExchange$DHEPossession.<init>(Unknown Source)
        at java.base/sun.security.ssl.DHClientKeyExchange$DHClientKeyExchangeProducer.produce(Unknown Source)
        at java.base/sun.security.ssl.ClientKeyExchange$ClientKeyExchangeProducer.produce(Unknown Source)
        at java.base/sun.security.ssl.SSLHandshake.produce(Unknown Source)
        at java.base/sun.security.ssl.ServerHelloDone$ServerHelloDoneConsumer.consume(Unknown Source)
        at java.base/sun.security.ssl.SSLHandshake.consume(Unknown Source)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(Unknown Source)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.dispatch(Unknown Source)
        at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
        ... 13 more
      Caused by: java.security.InvalidAlgorithmParameterException: DH key size must be multiple of 64, and can only range from 512 to 8192 (inclusive). The specific key size 2236 is not supported
        at java.base/com.sun.crypto.provider.DHKeyPairGenerator.initialize(Unknown Source)
        at java.base/java.security.KeyPairGenerator$Delegate.initialize(Unknown Source)
        ... 25 more

      We initially thought that the combination of Java requiring key lengths to be multiple of 64, and the server presenting an odd-sized one was just incompatible. But then a specialist analyzed the TLS handshake and pointed out the following:

      "[the server] uses 2240(0x118) length DH P value when using DHE as key exchange method and the most significant digit of P value is 0x0C( P value starts from 0x0C and ends at 0X63 as highlighted ), therefore, there are 4 leading zero omitted by Java Security Provider [...] which leads to the issue(2240-4=2236)."

      When using BouncyCastle, the problem does not occur and our application can connect to the web server. We therefore suspect that problem lies in Java's Diffie-Hellman implementation.

      We don't have a plain text version of the handshake, but can provide a screenshot if required.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Set up a we bserver which uses Diffie-Hellman (DHE) ciphers. It must use a key with the length of 2240 which contains 4 leading zeros.
      2. Establish a connection from Java to the web server (e.g. requesting a page).

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The SSL handshake succeeds and the connection is established because the key length (2240) is a multiple of 64.
      ACTUAL -
      The handshake fails because the key's leading zeros are ignored. This makes the key appear as if it had a length of 2236, which is not a multiple of 64.

      CUSTOMER SUBMITTED WORKAROUND :
      Use an alternative crypto provider like BouncyCastle.

      FREQUENCY : always


            xuelei Xuelei Fan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: