Why does SSL handshake give 'Could not generate DH keypair' exception?
Asked Answered
F

22

150

When I make an SSL connection with some IRC servers (but not others - presumably due to the server's preferred encryption method) I get the following exception:

Caused by: java.lang.RuntimeException: Could not generate DH keypair
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:106)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:556)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:183)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    ... 3 more

Final cause:

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:100)
    ... 10 more

An example of a server that demonstrates this problem is aperture.esper.net:6697 (this is an IRC server). An example of a server that does not demonstrate the problem is kornbluth.freenode.net:6697. [Not surprisingly, all servers on each network share the same respective behaviour.]

My code (which as noted does work when connecting to some SSL servers) is:

    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(null, trustAllCerts, new SecureRandom());
    s = (SSLSocket)sslContext.getSocketFactory().createSocket();
    s.connect(new InetSocketAddress(host, port), timeout);
    s.setSoTimeout(0);
    ((SSLSocket)s).startHandshake();

It's that last startHandshake that throws the exception. And yes there is some magic going on with the 'trustAllCerts'; that code forces the SSL system not to validate certs. (So... not a cert problem.)

Obviously one possibility is that esper's server is misconfigured, but I searched and didn't find any other references to people having problems with esper's SSL ports, and 'openssl' connects to it (see below). So I'm wondering if this is a limitation of Java default SSL support, or something. Any suggestions?

Here's what happens when I connect to aperture.esper.net 6697 using 'openssl' from commandline:

~ $ openssl s_client -connect aperture.esper.net:6697
CONNECTED(00000003)
depth=0 /C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/[email protected]
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/[email protected]
verify return:1
---
Certificate chain
 0 s:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/[email protected]
   i:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/[email protected]
---
Server certificate
-----BEGIN CERTIFICATE-----
[There was a certificate here, but I deleted it to save space]
-----END CERTIFICATE-----
subject=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/[email protected]
issuer=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/[email protected]
---
No client certificate CA names sent
---
SSL handshake has read 2178 bytes and written 468 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 51F1D40A1B044700365D3BD1C61ABC745FB0C347A334E1410946DCB5EFE37AFD
    Session-ID-ctx: 
    Master-Key: DF8194F6A60B073E049C87284856B5561476315145B55E35811028C4D97F77696F676DB019BB6E271E9965F289A99083
    Key-Arg   : None
    Start Time: 1311801833
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

As noted, after all that, it does connect successfully which is more than you can say for my Java app.

Should it be relevant, I'm using OS X 10.6.8, Java version 1.6.0_26.

Fullblooded answered 27/7, 2011 at 21:29 Comment(3)
The reason seems to be this: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive). No idea what size was sent by the server here, and what the specification says about this.Perjury
@PaŭloEbermann: Actually you can see the size the server used in the openssl output in the question: "Cipher is DHE-RSA-AES256-SHA, Server public key is 2048 bit". And 2048 > 1024 :-).Flit
@sleske: not exactly. Server public key (size) was, and is, the key in the cert. s_client in 2011 didn't show ephemeral key at all; 1.0.2 in 2015 and up does as Server Temp Key several lines higher. Although a good server usually should make DHE size same as RSA-auth size.Woodland
D
123

The problem is the prime size. The maximum-acceptable size that Java accepts is 1024 bits. This is a known issue (see JDK-6521495).

The bug report that I linked to mentions a workaround using BouncyCastle's JCE implementation. Hopefully that should work for you.

UPDATE

This was reported as bug JDK-7044060 and fixed recently.

Note, however, that the limit was only raised to 2048 bit. For sizes > 2048 bit, there is JDK-8072452 - Remove the maximum prime size of DH Keys; the fix appears to be for 9.

Donaghue answered 27/7, 2011 at 22:39 Comment(11)
+1. Everyone who has a Sun Developer Network Account, please vote for this bug.Perjury
Thanks. Seems a pretty serious problem given the existence of servers which request a larger size! :( I tried BouncyCastle; if you set it up as preferred provider it crashes with a different exception (sigh), and I can't see an obvious way to use that just for DH. However, I found an alternative solution, which I'll add as a new answer. (It's not pretty.)Fullblooded
Cool. This has been fixed in newer versions of Java. But my question is about using older version.. When I use older version, sometimes it works and sometimes it gives above exception..Why so random behaviour? If its a bug in java, then I guess it should never work?Koziol
This has not been fixed. The limit was changed from 1024 to 2048. Thus a prime size > 2048 yields the same errorIrrationality
The 2048 fix was backported to IcedTea 2.5.3 . Newer versions of IcedTea increased it to 4096.Nematode
When I updated Java on the machine, this issue went away.Attenuate
Is it also fixed for 4096bit keys with java 1.8.0_51 on Ubuntu 14.04? Because I'm getting the same error while trying to connect to a server.Couperin
@bebbo: Correct. Support for primes > 2048 bit was requested in JDK-8072452 - Remove the maximum prime size of DH Keys.Flit
@sleske: A request does not mean it has already been changed. Such a limitation is simply superfluous. Right now it's not available.Irrationality
The problem is the DH prime size. The maximum-acceptable size that Java accepts is 2048 bits. While we wait for Oracle to expand the limit, you can compile with Excelsior Jet which has an expanded limit.Toitoiboid
@N it depends on the server configuration. The bug only manifests if the server chooses a DHE ciphersuite and then sends a prime that the client considers too large. It is seen less often with Java 7 than Java 6 because Java 7 supports ECDHE and most server's preffer ECDHE over DHE.Grower
P
70

The "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" answer did not work for me but The BouncyCastle's JCE provider suggestion did.

Here are the steps I took using Java 1.6.0_65-b14-462 on Mac OSC 10.7.5

1) Download these jars:

2) move these jars to $JAVA_HOME/lib/ext

3) edit $JAVA_HOME/lib/security/java.security as follows: security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider

restart app using JRE and give it a try

Periphrastic answered 20/3, 2015 at 22:12 Comment(4)
security.provider.2=org.bouncycastle.jce.provider.BouncyCastleProvider did work better, putting it on 1. resulted in errors in default software.Arjan
This works for me too, but I have added a provider dynamically. Reffer my answer here for details.Indisposition
Thanks a ton, this worked for me and was required in order to successfully build the Tomcat 7.0.78 source.Misconstruction
@mjj1409, in Java 1.5 we don't have $JAVA_HOME/lib/security pathSwarey
W
16

Here is my solution (java 1.6), also would be interested why I had to do this:

I noticed from the javax.security.debug=ssl, that sometimes the used cipher suite is TLS_DHE_... and sometime it is TLS_ECDHE_.... The later would happen if I added BouncyCastle. If TLS_ECDHE_ was selected, MOST OF the time it worked, but not ALWAYS, so adding even BouncyCastle provider was unreliable (failed with same error, every other time or so). I guess somewhere in the Sun SSL implementation sometimes it choose DHE, sometimes it choose ECDHE.

So the solution posted here relies on removing TLS_DHE_ ciphers completely. NOTE: BouncyCastle is NOT required for the solution.

So create the server certification file by:

echo |openssl s_client -connect example.org:443 2>&1 |sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

Save this as it will be referenced later, than here is the solution for an SSL http get, excluding the TLS_DHE_ cipher suites.

package org.example.security;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import org.apache.log4j.Logger;

public class SSLExcludeCipherConnectionHelper {

    private Logger logger = Logger.getLogger(SSLExcludeCipherConnectionHelper.class);

    private String[] exludedCipherSuites = {"_DHE_","_DH_"};

    private String trustCert = null;

    private TrustManagerFactory tmf;

    public void setExludedCipherSuites(String[] exludedCipherSuites) {
        this.exludedCipherSuites = exludedCipherSuites;
    }

    public SSLExcludeCipherConnectionHelper(String trustCert) {
        super();
        this.trustCert = trustCert;
        //Security.addProvider(new BouncyCastleProvider());
        try {
            this.initTrustManager();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void initTrustManager() throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = new BufferedInputStream(new FileInputStream(trustCert));
        Certificate ca = null;
        try {
            ca = cf.generateCertificate(caInput);
            logger.debug("ca=" + ((X509Certificate) ca).getSubjectDN());
        } finally {
            caInput.close();
        }

        // Create a KeyStore containing our trusted CAs
        KeyStore keyStore = KeyStore.getInstance("jks");
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);
    }

    public String get(URL url) throws Exception {
        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);
        SSLParameters params = context.getSupportedSSLParameters();
        List<String> enabledCiphers = new ArrayList<String>();
        for (String cipher : params.getCipherSuites()) {
            boolean exclude = false;
            if (exludedCipherSuites != null) {
                for (int i=0; i<exludedCipherSuites.length && !exclude; i++) {
                    exclude = cipher.indexOf(exludedCipherSuites[i]) >= 0;
                }
            }
            if (!exclude) {
                enabledCiphers.add(cipher);
            }
        }
        String[] cArray = new String[enabledCiphers.size()];
        enabledCiphers.toArray(cArray);

        // Tell the URLConnection to use a SocketFactory from our SSLContext
        HttpsURLConnection urlConnection =
            (HttpsURLConnection)url.openConnection();
        SSLSocketFactory sf = context.getSocketFactory();
        sf = new DOSSLSocketFactory(sf, cArray);
        urlConnection.setSSLSocketFactory(sf);
        BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
        String inputLine;
        StringBuffer buffer = new StringBuffer();
        while ((inputLine = in.readLine()) != null) 
            buffer.append(inputLine);
        in.close();

        return buffer.toString();
    }

    private class DOSSLSocketFactory extends javax.net.ssl.SSLSocketFactory {

        private SSLSocketFactory sf = null;
        private String[] enabledCiphers = null;

        private DOSSLSocketFactory(SSLSocketFactory sf, String[] enabledCiphers) {
            super();
            this.sf = sf;
            this.enabledCiphers = enabledCiphers;
        }

        private Socket getSocketWithEnabledCiphers(Socket socket) {
            if (enabledCiphers != null && socket != null && socket instanceof SSLSocket)
                ((SSLSocket)socket).setEnabledCipherSuites(enabledCiphers);

            return socket;
        }

        @Override
        public Socket createSocket(Socket s, String host, int port,
                boolean autoClose) throws IOException {
            return getSocketWithEnabledCiphers(sf.createSocket(s, host, port, autoClose));
        }

        @Override
        public String[] getDefaultCipherSuites() {
            return sf.getDefaultCipherSuites();
        }

        @Override
        public String[] getSupportedCipherSuites() {
            if (enabledCiphers == null)
                return sf.getSupportedCipherSuites();
            else
                return enabledCiphers;
        }

        @Override
        public Socket createSocket(String host, int port) throws IOException,
                UnknownHostException {
            return getSocketWithEnabledCiphers(sf.createSocket(host, port));
        }

        @Override
        public Socket createSocket(InetAddress address, int port)
                throws IOException {
            return getSocketWithEnabledCiphers(sf.createSocket(address, port));
        }

        @Override
        public Socket createSocket(String host, int port, InetAddress localAddress,
                int localPort) throws IOException, UnknownHostException {
            return getSocketWithEnabledCiphers(sf.createSocket(host, port, localAddress, localPort));
        }

        @Override
        public Socket createSocket(InetAddress address, int port,
                InetAddress localaddress, int localport) throws IOException {
            return getSocketWithEnabledCiphers(sf.createSocket(address, port, localaddress, localport));
        }

    }
}

Finally here is how it is used (certFilePath if the path of the certificate saved from openssl):

try {
            URL url = new URL("https://www.example.org?q=somedata");            
            SSLExcludeCipherConnectionHelper sslExclHelper = new SSLExcludeCipherConnectionHelper(certFilePath);
            logger.debug(
                    sslExclHelper.get(url)
            );
        } catch (Exception ex) {
            ex.printStackTrace();
        }
Woodberry answered 15/8, 2013 at 13:47 Comment(5)
Just tested your solution. It's working as intended. Thanks. Actually, just adding jdk.tls.disabledAlgorithms=DHE, ECDHE in JDK_HOME/jre/lib/security/java.security also works and avoid all this code.Gramnegative
Just disabling DHE worked for me: jdk.tls.disabledAlgorithms=DHE. Using 1.7.0_85-b15.Currish
Added jdk.tls.disabledAlgorithms=DHE, ECDHE in JDK_HOME/jre/lib/security/java.security and worked fine! Thank you! Using 1.7.0_79Dort
Don't disable ECDHE. It's different than DHE and does not even use prime numbers.Eng
Can someone please tell me how i can get the 'certFilePath'. I've been stuck on this for a week. @WoodberryScutari
F
14

The answer above is correct, but in terms of the workaround, I had problems with the BouncyCastle implementation when I set it as preferred provider:

java.lang.ArrayIndexOutOfBoundsException: 64
    at com.sun.crypto.provider.TlsPrfGenerator.expand(DashoA13*..)

This is also discussed in one forum thread I found, which doesn't mention a solution. http://www.javakb.com/Uwe/Forum.aspx/java-programmer/47512/TLS-problems

I found an alternative solution which works for my case, although I'm not at all happy with it. The solution is to set it so that the Diffie-Hellman algorithm is not available at all. Then, supposing the server supports an alternative algorithm, it will be selecting during normal negotiation. Obviously the downside of this is that if somebody somehow manages to find a server that only supports Diffie-Hellman at 1024 bits or less then this actually means it will not work where it used to work before.

Here is code which works given an SSLSocket (before you connect it):

List<String> limited = new LinkedList<String>();
for(String suite : ((SSLSocket)s).getEnabledCipherSuites())
{
    if(!suite.contains("_DHE_"))
    {
        limited.add(suite);
    }
}
((SSLSocket)s).setEnabledCipherSuites(limited.toArray(
    new String[limited.size()]));

Nasty.

Fullblooded answered 28/7, 2011 at 16:30 Comment(4)
Sad that this is the only way :(. That ticket has been open since '07. Strange that nothing has been done about it in 4 years.Donaghue
I am new to java securities. Please help where should I write this piece of code?Oology
I tried every solution in this thread and this was the only one that worked with my ibm jvm (ibm-java-s390x-60).Pinite
@Sam , What's s variable in ((SSLSocket)s) ?Swarey
E
13

You can disable DHE completely in your jdk, edit jre/lib/security/java.security and make sure DHE is disabled, eg. like

jdk.tls.disabledAlgorithms=SSLv3, DHE.

Exercitation answered 10/7, 2015 at 7:44 Comment(2)
that is only available in JDK 1.7 and later. linkApostrophize
Solved the problem for me JDK 1.8.0_144-b01Deidradeidre
C
12

You can installing the provider dynamically:

1) Download these jars:

  • bcprov-jdk15on-152.jar
  • bcprov-ext-jdk15on-152.jar

2) Copy jars to WEB-INF/lib (or your classpath)

3) Add provider dynamically:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());

Coccyx answered 7/5, 2015 at 12:44 Comment(3)
This solution works well, and was a good fit for my case since I wanted to make the changes only at the project level and not at the server/environment level. ThanksStandoff
Thanks! this worked for me. In my case it was itext importing bcp 1.4 causing emails to google to fail.Mcdougald
I am getting javax.net.ssl.SSLHandshakeException: Unsupported curveId: 29 with java version 1.6.0_27People
B
8

This is a quite old post, but if you use Apache HTTPD, you can limit the DH size. See http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

Blacking answered 19/11, 2014 at 17:8 Comment(0)
W
7

It is possible that you have incorrect Maven dependencies. You must find these libraries in Maven dependency hierarchy:

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

If you have these dependencies that is the error, and you should do this:

Add the dependency:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcmail-jdk15on</artifactId>
    <version>1.59</version>
</dependency>

Exclude these dependencies from the artifact that included the wrong dependencies, in my case it is:

<dependency>
    <groupId>com.lowagie</groupId>
    <artifactId>itext</artifactId>
    <version>2.1.7</version>
    <exclusions>
        <exclusion>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bctsp-jdk14</artifactId>                
        </exclusion>
        <exclusion>
            <groupId>bouncycastle</groupId>
            <artifactId>bcprov-jdk14</artifactId>               
        </exclusion>
        <exclusion>
            <groupId>bouncycastle</groupId>
            <artifactId>bcmail-jdk14</artifactId>               
        </exclusion>
    </exclusions>       
</dependency>
Whangee answered 22/3, 2018 at 9:3 Comment(0)
N
6

If you are using jdk1.7.0_04, upgrade to jdk1.7.0_21. The problem has been fixed in that update.

Nauplius answered 22/5, 2013 at 8:29 Comment(5)
I just downloaded Java SE Development Kit 7u25, and according to the little program I wrote to determine the maximum supported DH size, it's still 1024.Surly
Problem still exists with JDK 1.7.0_25Mallory
updating jre worked for me .had 6.22 updated to 7.59 . problem solved.Israel
@Oology - Upgrading to JDK 1.8.0_73 worked for me.Localize
DHKeyPairs with Bit Lengths Greater Than 1024 introduced from JDK 1.7.0_91 but isn't available public.People
M
5

Try downloading "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" from the Java download site and replacing the files in your JRE.

This worked for me and I didn't even need to use BouncyCastle - the standard Sun JCE was able to connect to the server.

PS. I got the same error (ArrayIndexOutOfBoundsException: 64) when I tried using BouncyCastle before changing the policy files, so it seems our situation is very similar.

Matinee answered 17/11, 2011 at 21:2 Comment(2)
have you done anyhting else? or just copied the 2 files into the folder?Pooka
It's been a while but as far as I remember, that was all I needed to do. Apart from restarting any running Java processes afterwards.Matinee
E
5

If you are still bitten by this issue AND you are using Apache httpd v> 2.4.7, try this: http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

copied from the url:

Beginning with version 2.4.7, mod_ssl will use DH parameters which include primes with lengths of more than 1024 bits. Java 7 and earlier limit their support for DH prime sizes to a maximum of 1024 bits, however.

If your Java-based client aborts with exceptions such as java.lang.RuntimeException: Could not generate DH keypair and java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive), and httpd logs tlsv1 alert internal error (SSL alert number 80) (at LogLevel info or higher), you can either rearrange mod_ssl's cipher list with SSLCipherSuite (possibly in conjunction with SSLHonorCipherOrder), or you can use custom DH parameters with a 1024-bit prime, which will always have precedence over any of the built-in DH parameters.

To generate custom DH parameters, use the

openssl dhparam 1024

command. Alternatively, you can use the following standard 1024-bit DH parameters from RFC 2409, section 6.2:

-----BEGIN DH PARAMETERS-----
MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
-----END DH PARAMETERS-----

Add the custom parameters including the "BEGIN DH PARAMETERS" and "END DH PARAMETERS" lines to the end of the first certificate file you have configured using the SSLCertificateFile directive.


I am using java 1.6 on client side, and it solved my issue. I didn't lowered the cipher suites or like, but added a custom generated DH param to the cert file..

Elastin answered 14/11, 2015 at 18:57 Comment(1)
Be aware that it is now believed that 1024 bit DH is computationally feasible (though hellishly expensive) to break.Grower
I
3

I have the same problem with Yandex Maps server, JDK 1.6 and Apache HttpClient 4.2.1. The error was

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

with enabled debug by -Djavax.net.debug=all there was a message in a log

Could not generate DH keypair

I have fixed this problem by adding BouncyCastle library bcprov-jdk16-1.46.jar and registering a provider in a map service class

public class MapService {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public GeocodeResult geocode() {

    }

}

A provider is registered at the first usage of MapService.

Indisposition answered 21/11, 2015 at 17:11 Comment(0)
T
2

I encountered the SSL error on a CentOS server running JDK 6.

My plan was to install a higher JDK version (JDK 7) to co-exist with JDK 6 but it turns out that merely installing the newer JDK with rpm -i was not enough.

The JDK 7 installation would only succeed with the rpm -U upgrade option as illustrated below.

1. Download JDK 7

wget -O /root/jdk-7u79-linux-x64.rpm --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; o raclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.rpm"

2. RPM installation fails

rpm -ivh jdk-7u79-linux-x64.rpm
Preparing...                ########################################### [100%]
        file /etc/init.d/jexec from install of jdk-2000:1.7.0_79-fcs.x86_64 conflicts with file from package jdk-2000:1.6.0_43-fcs.x86_64

3. RPM upgrade succeeds

rpm -Uvh jdk-7u79-linux-x64.rpm
Preparing...                ########################################### [100%]
   1:jdk                    ########################################### [100%]
Unpacking JAR files...
        rt.jar...
        jsse.jar...
        charsets.jar...
        tools.jar...
        localedata.jar...
        jfxrt.jar...

4. Confirm the new version

java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
Theurer answered 16/3, 2017 at 16:25 Comment(0)
R
1

Solved the problem by upgrading to JDK 8.

Raney answered 1/6, 2016 at 15:8 Comment(0)
W
1

I use coldfusion 8 on JDK 1.6.45 and had problems with <cfdocument ...> giving me just red crosses instead of images, and also with cfhttp not able to connect to the local webserver with ssl.

my test script to reproduce with coldfusion 8 was

<CFHTTP URL="https://www.onlineumfragen.com" METHOD="get" ></CFHTTP>
<CFDUMP VAR="#CFHTTP#">

this gave me the quite generic error of " I/O Exception: peer not authenticated." I then tried to add certificates of the server including root and intermediate certificates to the java keystore and also the coldfusion keystore, but nothing helped. then I debugged the problem with

java SSLPoke www.onlineumfragen.com 443

and got

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair

and

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be
multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:107)
    ... 10 more

I then had the idea that the webserver (apache in my case) had very modern ciphers for ssl and is quite restrictive (qualys score a+) and uses strong Diffie-hellman groups with more than 1024 bits. Obviously, ColdFusion and Java JDK 1.6.45 can not manage this. Next step in the odyssey was to think of installing an alternative security provider for java, and I decided for bouncy castle. see also http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

I then downloaded the

bcprov-ext-jdk15on-156.jar

from http://www.bouncycastle.org/latest_releases.html and installed it under C:\jdk6_45\jre\lib\ext or where ever your jdk is, in original install of coldfusion 8 it would be under C:\JRun4\jre\lib\ext but I use a newer jdk (1.6.45) located outside the coldfusion directory. it is very important to put the bcprov-ext-jdk15on-156.jar in the \ext directory (this cost me about two hours and some hair ;-) then I edited the file C:\jdk6_45\jre\lib\security\java.security (with wordpad not with editor.exe!) and put in one line for the new provider. afterwards the list looked like

#
# List of providers and their preference orders (see above):
#
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI

(see the new one in position 1)

then restart coldfusion service completely. you can then

java SSLPoke www.onlineumfragen.com 443 (or of course your url!)

and enjoy the feeling... and of course <cfhttp and <cfdocument worked like a charm and like before we "hardened" our ssl ciphers in apache!

what a night and what a day. Hopefully this will help (partially or fully) to someone out there. if you have questions, just mail me at info ... (domain above).

Wildee answered 5/1, 2017 at 16:28 Comment(0)
T
0

We got the same exact exception error returned, to fix it was easy after hours surfing the internet.

We downloaded the highest version of jdk we could find on oracle.com, installed it and pointed Jboss application server to the directory of the installed new jdk.

Restarted Jboss, reprocessed, problemo fixed!!!

Tipperary answered 5/4, 2016 at 16:20 Comment(0)
F
0

I've got this error with Bamboo 5.7 + Gradle project + Apache. Gradle tried to get some dependencies from one of our servers via SSL.

Solution:

  1. Generate DH Param:

with OpenSSL:

openssl dhparam 1024

example output:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. Append output to certificate file (for Apache - SSLCertificateFile param)

  2. Restart apache

  3. Restart Bamboo

  4. Try to build project again

Furnivall answered 5/12, 2016 at 7:59 Comment(0)
R
0

I used to get a similar error accessing svn.apache.org with java SVN clients using an IBM JDK. Currently, svn.apache.org users the clients cipher preferences.

After running just once with a packet capture / javax.net.debug=ALL I was able to blacklist just a single DHE cipher and things work for me (ECDHE is negotiated instead).

.../java/jre/lib/security/java.security:
    jdk.tls.disabledAlgorithms=SSL_DHE_RSA_WITH_AES_256_CBC_SHA

A nice quick fix when it is not easy to change the client.

Rawhide answered 7/1, 2017 at 17:0 Comment(0)
B
0

Recently I have the same issue and after upgrading jdk version from 1.6.0_45 to jdk1.7.0_191 which resolved the issue.

Billhook answered 8/8, 2018 at 19:33 Comment(0)
W
-1

If the server supports a cipher that does not include DH, you can force the client to select that cipher and avoid the DH error. Such as:

String pickedCipher[] ={"TLS_RSA_WITH_AES_256_CBC_SHA"};
sslsocket.setEnabledCipherSuites(pickedCipher);

Keep in mind that specifying an exact cipher is prone to breakage in the long run.

Wherefore answered 1/7, 2015 at 23:33 Comment(0)
I
-1

For me, the following command line fixed the issue:

java -jar -Dhttps.protocols=TLSv1.2 -Ddeployment.security.TLSv1.2=true -Djavax.net.debug=ssl:handshake XXXXX.jar

I am using JDK 1.7.0_79

Invulnerable answered 18/10, 2016 at 20:17 Comment(1)
I faced same situation using JDK 1.7.0_xx. BY default issue will be solved after using jdk 1.8. But sometime we can not upgrade jdk quickly. So my issue solved after adding system configuration: System.setProperty("https.protocols", "TLSv1.2"); System.setProperty("deployment.security.TLSv1.2", "true");Adenoidal
S
-1

Window -> Preferences -> Java -> Installed JREs ->select the jre and Edit. And in the Default VM Arguments enter

-Dcom.sun.net.ssl.enableECC=false

Click Finish

Shavian answered 14/9, 2022 at 5:50 Comment(1)
This is a very old question and you'll note there are discussion about various Java versions - so does your parameter apply? Also, you don't provide details of what this does or why someone should try it. Lastly, it looks as though you may be talking about a Windows only solution, if so you should highlight that as the OP was OS X focused.Consistence

© 2022 - 2024 — McMap. All rights reserved.