¿Por qué el protocolo de enlace SSL da la excepción 'No se pudo generar el par de claves DH'?

142

Cuando establezco una conexión SSL con algunos servidores IRC (pero no con otros, probablemente debido al método de cifrado preferido del servidor) obtengo la siguiente excepción:

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

Causa final:

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

Un ejemplo de un servidor que demuestra este problema es aperture.esper.net:6697 (este es un servidor IRC). Un ejemplo de un servidor que no demuestra el problema es kornbluth.freenode.net:6697. [No es sorprendente que todos los servidores de cada red compartan el mismo comportamiento respectivo].

Mi código (que, como se señaló, funciona cuando me conecto a algunos servidores SSL) es:

    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();

Es ese último comienzo, Handshake, lo que arroja la excepción. Y sí, hay algo de magia con el 'trustAllCerts'; ese código obliga al sistema SSL a no validar certs. (Entonces ... no es un problema de cert.)

Obviamente, una posibilidad es que el servidor de esper esté mal configurado, pero busqué y no encontré ninguna otra referencia a personas que tienen problemas con los puertos SSL de esper, y 'openssl' se conecta a él (ver más abajo). Así que me pregunto si esto es una limitación del soporte SSL predeterminado de Java, o algo así. ¿Alguna sugerencia?

Esto es lo que sucede cuando me conecto a aperture.esper.net 6697 usando 'openssl' desde la línea de comandos:

~ $ 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/emailAddress=support@esper.net
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/emailAddress=support@esper.net
verify return:1
---
Certificate chain
 0 s:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
   i:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
---
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/emailAddress=support@esper.net
issuer=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
---
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)
---

Como se señaló, después de todo eso, se conecta con éxito, lo que es más de lo que puedes decir para mi aplicación Java.

Si fuera relevante, estoy usando OS X 10.6.8, Java versión 1.6.0_26.

sam
fuente
2
La razón parece ser la siguiente: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive). No tengo idea de qué tamaño envió el servidor aquí, y qué dice la especificación sobre esto.
Paŭlo Ebermann
@ PaŭloEbermann: En realidad, puede ver el tamaño que el servidor usó en la opensslsalida en la pregunta: "Cipher es DHE-RSA-AES256-SHA, la clave pública del servidor es 2048 bit". Y 2048> 1024 :-).
sleske
@sleske: no exactamente. Server public key (size)fue, y es, la clave en el certificado. s_clienten 2011 no mostró clave efímera en absoluto; 1.0.2 en 2015 y hasta hace Server Temp Keyvarias líneas más arriba. Aunque un buen servidor generalmente debería hacer que el tamaño de DHE sea igual al tamaño de autenticación RSA.
dave_thompson_085

Respuestas:

117

El problema es el tamaño principal. El tamaño máximo aceptable que acepta Java es 1024 bits. Este es un problema conocido (ver JDK-6521495 ).

El informe de error al que vinculé menciona una solución alternativa usando la implementación JCE de BouncyCastle. Espero que eso funcione para ti.

ACTUALIZAR

Esto se informó como error JDK-7044060 y se corrigió recientemente.

Sin embargo, tenga en cuenta que el límite solo se aumentó a 2048 bits. Para tamaños> 2048 bits, hay JDK-8072452: elimine el tamaño de cebado máximo de las llaves DH ; la solución parece ser para 9.

Vivin Paliath
fuente
14
+1. Todos los que tengan una cuenta de Sun Developer Network, voten por este error.
Paŭlo Ebermann
1
Gracias. ¡Parece un problema bastante serio dada la existencia de servidores que solicitan un tamaño más grande! :( Intenté BouncyCastle; si lo configura como proveedor preferido, se bloquea con una excepción diferente (suspiro), y no puedo ver una forma obvia de usar eso solo para DH. Sin embargo, encontré una solución alternativa, que Agregaré como una nueva respuesta. (No es bonito.)
sam
3
Frio. Esto se ha solucionado en las versiones más recientes de Java. Pero mi pregunta es sobre el uso de una versión anterior ... Cuando uso una versión anterior, a veces funciona y a veces da la excepción anterior ... ¿Por qué un comportamiento tan aleatorio? Si es un error en Java, entonces supongo que nunca debería funcionar.
N ..
2
La corrección de 2048 se hizo retroceder a IcedTea 2.5.3. Las versiones más nuevas de IcedTea lo aumentaron a 4096.
fuzzyTew
1
El problema es el tamaño principal de DH. El tamaño máximo aceptable que acepta Java es de 2048 bits. Mientras esperamos que Oracle amplíe el límite, puede compilar con Excelsior Jet, que tiene un límite ampliado.
user1332994
67

La respuesta "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" no me funcionó, pero la sugerencia del proveedor de The BouncyCastle JCE sí.

Estos son los pasos que tomé usando Java 1.6.0_65-b14-462 en Mac OSC 10.7.5

1) Descargue estos frascos:

2) mueva estos frascos a $ JAVA_HOME / lib / ext

3) edite $ JAVA_HOME / lib / security / java.security de la siguiente manera: security.provider.1 = org.bouncycastle.jce.provider.BouncyCastleProvider

reinicie la aplicación con JRE y pruébela

mjj1409
fuente
55
¡funciona para mi! aunque no estoy muy seguro de lo que estoy haciendo.
DiveInto
11
security.provider.2 = org.bouncycastle.jce.provider.BouncyCastleProvider funcionó mejor, ponerlo en 1. resultó en errores en el software predeterminado.
TinusSky
1
Esto también funciona para mí, pero he agregado un proveedor dinámicamente. Refiera mi respuesta aquí para más detalles.
v.ladynev
Muchas gracias, esto funcionó para mí y fue necesario para construir con éxito la fuente Tomcat 7.0.78.
phillipuniverse
@ mjj1409, en Java 1.5 no tenemos $ JAVA_HOME / lib / security path
Mostafa
15

Aquí está mi solución (Java 1.6), también estaría interesado por qué tuve que hacer esto:

Me di cuenta por el javax.security.debug = ssl, que a veces el conjunto de cifrado utilizado es TLS_DHE _... y a veces es TLS_ECDHE _.... Lo último sucedería si agrego BouncyCastle. Si se seleccionó TLS_ECDHE_, la MAYORÍA del tiempo funcionó, pero NO SIEMPRE, por lo que agregar incluso el proveedor BouncyCastle no era confiable (falló con el mismo error, cada dos veces más o menos). Supongo que en algún lugar de la implementación de SSL de Sun a veces elige DHE , a veces elige ECDHE .

Entonces, la solución publicada aquí se basa en eliminar los cifrados TLS_DHE_ completamente. NOTA: BouncyCastle NO es necesario para la solución.

Así que cree el archivo de certificación del servidor de la siguiente manera:

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

Guarde esto, ya que se hará referencia más adelante, que aquí está la solución para un HTTP http get, excluyendo los conjuntos de cifrado TLS_DHE_.

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));
        }

    }
}

Finalmente, así es como se usa (certFilePath si la ruta del certificado se guardó desde 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();
        }
Zsozso
fuente
9
Acabo de probar tu solución. Funciona según lo previsto. Gracias. En realidad, sólo añadir jdk.tls.disabledAlgorithms=DHE, ECDHEen el JDK_HOME/jre/lib/security/java.securityque también trabaja y evitar todo este código.
Ludovic Guillaume
3
Simplemente desactivando DHE trabajó para mí: jdk.tls.disabledAlgorithms=DHE. Usando 1.7.0_85-b15.
stephan f
1
Se agregó jdk.tls.disabledAlgorithms = DHE, ECDHE en JDK_HOME / jre / lib / security / java.security y funcionó bien. ¡Gracias! Usando 1.7.0_79
Eric Na
1
No deshabilite ECDHE. Es diferente a DHE y ni siquiera usa números primos.
kubanczyk
1
¿Puede alguien decirme cómo puedo obtener el 'certFilePath'? He estado atrapado en esto por una semana. @Zsozso
user1172490
13

La respuesta anterior es correcta, pero en términos de la solución, tuve problemas con la implementación de BouncyCastle cuando la configuré como proveedor preferido:

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

Esto también se discute en un hilo del foro que encontré, que no menciona una solución. http://www.javakb.com/Uwe/Forum.aspx/java-programmer/47512/TLS-problems

Encontré una solución alternativa que funciona para mi caso, aunque no estoy nada contento con ella. La solución es configurarlo para que el algoritmo Diffie-Hellman no esté disponible en absoluto. Luego, suponiendo que el servidor admita un algoritmo alternativo, se seleccionará durante la negociación normal. Obviamente, la desventaja de esto es que si alguien de alguna manera logra encontrar un servidor que solo sea compatible con Diffie-Hellman a 1024 bits o menos, esto significa que no funcionará donde solía funcionar antes.

Aquí hay un código que funciona dado un SSLSocket (antes de conectarlo):

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()]));

Asqueroso.

sam
fuente
1
Triste que esta sea la única manera :(. Ese boleto ha estado abierto desde '07. Es extraño que no se haya hecho nada al respecto en 4 años.
Vivin Paliath
Soy nuevo en los valores de Java. Por favor, ayuda, ¿dónde debo escribir este código?
Shashank
Probé todas las soluciones en este hilo y esta fue la única que funcionó con mi ibm jvm (ibm-java-s390x-60).
Gianluca Greco
@Sam, ¿Cuál es la variable en ((SSLSocket) s)?
Mostafa
13

Puede deshabilitar DHE por completo en su jdk, editar jre / lib / security / java.security y asegurarse de que DHE esté deshabilitado, por ejemplo. me gusta

jdk.tls.disabledAlgorithms=SSLv3, DHE.

Colina
fuente
44
eso solo está disponible en JDK 1.7 y versiones posteriores. enlace
hoangthienan
Resolvió el problema para mí JDK 1.8.0_144-b01
MrSmith42
12

Puede instalar el proveedor dinámicamente:

1) Descargue estos frascos:

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

2) Copiar frascos a WEB-INF/lib(o su classpath)

3) Agregar proveedor dinámicamente:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());

angelcorral
fuente
Esta solución funciona bien y fue una buena opción para mi caso, ya que quería hacer los cambios solo a nivel de proyecto y no a nivel de servidor / entorno. Gracias
ishanbakshi
¡Gracias! Esto funcionó para mí. En mi caso, fue la importación de texto bcp 1.4 que causó el error de los correos electrónicos a google.
Japheth Ongeri - inkalimeva
Estoy obteniendo javax.net.ssl.SSLHandshakeException: curva no admitida Id: 29 con java versión 1.6.0_27
Otro codificador el
6

Si está utilizando jdk1.7.0_04, actualice a jdk1.7.0_21. El problema se ha solucionado en esa actualización.

Lekkie
fuente
2
Acabo de descargar Java SE Development Kit 7u25, y de acuerdo con el pequeño programa que escribí para determinar el tamaño máximo de DH admitido , todavía es 1024.
user2666524
1
El problema todavía existe con JDK 1.7.0_25
Sébastien Vanmechelen
actualizar jre funcionó para mí .had 6.22 actualizado a 7.59. problema resuelto.
Elazaron
1
@Shashank - La actualización a JDK 1.8.0_73 funcionó para mí.
dgoverde
DHKeyPairs con longitudes de bits superiores a 1024 introducido desde JDK 1.7.0_91 pero no está disponible públicamente.
Otro codificador
6

Es posible que tenga dependencias incorrectas de Maven. Debe encontrar estas bibliotecas en la jerarquía de dependencia de Maven:

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

Si tiene estas dependencias, ese es el error, y debe hacer esto:

Agregue la dependencia:

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

Excluir estas dependencias del artefacto que incluía las dependencias incorrectas, en mi caso es:

<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>
José Antonio Sánchez Pujante
fuente
La pregunta ya recibió muchas respuestas y tiene una respuesta validada. Además, la pregunta se hizo hace más de 6 años. No estoy seguro si sigue siendo relevante.
David Guyon
5

Intente descargar "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" del sitio de descarga de Java y reemplace los archivos en su JRE.

Esto funcionó para mí y ni siquiera necesité usar BouncyCastle: el Sun JCE estándar pudo conectarse al servidor.

PD. Obtuve el mismo error (ArrayIndexOutOfBoundsException: 64) cuando intenté usar BouncyCastle antes de cambiar los archivos de política, por lo que parece que nuestra situación es muy similar.

mjomble
fuente
¿has hecho algo más? o simplemente copió los 2 archivos en la carpeta?
Joergi
Ha pasado un tiempo, pero que yo recuerde, eso fue todo lo que necesitaba hacer. Además de reiniciar cualquier proceso Java en ejecución después.
mjomble
5

Si todavía le muerde este problema Y está usando Apache httpd v> 2.4.7, intente esto: http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

copiado de la url :

A partir de la versión 2.4.7, mod_ssl utilizará parámetros DH que incluyen primos con longitudes de más de 1024 bits. Sin embargo, Java 7 y versiones anteriores limitan su soporte para tamaños primos DH a un máximo de 1024 bits.

Si su cliente basado en Java aborta con excepciones como java.lang.RuntimeException: No se pudo generar el par de claves DH y java.security.InvalidAlgorithmParameterException: El tamaño principal debe ser múltiplo de 64 y solo puede variar de 512 a 1024 (inclusive), y httpd registra el error interno de alerta tlsv1 (número de alerta SSL 80) (en la información de LogLevel o superior), puede reorganizar la lista de cifrado de mod_ssl con SSLCipherSuite (posiblemente junto con SSLHonorCipherOrder), o puede usar parámetros DH personalizados con un primo de 1024 bits , que siempre tendrá prioridad sobre cualquiera de los parámetros DH incorporados.

Para generar parámetros DH personalizados, use el

openssl dhparam 1024

mando. Alternativamente, puede usar los siguientes parámetros DH estándar de 1024 bits de RFC 2409, sección 6.2:

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

Agregue los parámetros personalizados, incluidas las líneas "COMENZAR PARÁMETROS DH" y "FINALIZAR PARÁMETROS DH" al final del primer archivo de certificado que haya configurado utilizando la directiva SSLCertificateFile.


Estoy usando Java 1.6 en el lado del cliente, y resolvió mi problema. No bajé los conjuntos de cifrado o similares, pero agregué un parámetro DH generado personalizado al archivo cert.

pka
fuente
Tenga en cuenta que ahora se cree que el DH de 1024 bits es computacionalmente factible (aunque terriblemente costoso) romper.
plugwash
2

Tengo el mismo problema con el servidor Yandex Maps, JDK 1.6 y Apache HttpClient 4.2.1. El error fue

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

con depuración habilitada por -Djavax.net.debug=all había un mensaje en un registro

Could not generate DH keypair

He solucionado este problema agregando la biblioteca BouncyCastle bcprov-jdk16-1.46.jary registrando un proveedor en una clase de servicio de mapas

public class MapService {

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

    public GeocodeResult geocode() {

    }

}

Un proveedor se registra en el primer uso de MapService.

v.ladynev
fuente
2

Encontré el error SSL en un servidor CentOS que ejecuta JDK 6.

Mi plan era instalar una versión JDK más alta (JDK 7) para coexistir con JDK 6, pero resulta que simplemente instalar el JDK más nuevo rpm -ino era suficiente.

La instalación de JDK 7 solo tendrá éxito con la rpm -Uopción de actualización como se ilustra a continuación.

1. Descargar 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. La instalación de RPM falla

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. La actualización de RPM tiene éxito

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. Confirme la nueva versión.

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)
Saheed
fuente
1

Resolvió el problema actualizando a JDK 8.

anre
fuente
1

Utilizo coldfusion 8 en JDK 1.6.45 y tuve problemas para darme solo cruces rojas en lugar de imágenes, y también con cfhttp no puedo conectarme al servidor web local con ssl.

mi script de prueba para reproducir con coldfusion 8 fue

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

esto me dio el error bastante genérico de "Excepción de E / S: igual no autenticado". Luego intenté agregar certificados del servidor, incluidos los certificados raíz e intermedios, al almacén de claves de Java y también al almacén de claves de ColdFusion, pero nada ayudó. luego depuré el problema con

java SSLPoke www.onlineumfragen.com 443

y consiguió

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

y

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

Entonces tuve la idea de que el servidor web (apache en mi caso) tenía cifrados muy modernos para ssl y es bastante restrictivo (las calificaciones puntúan a +) y usa fuertes claves diffie hellmann con más de 1024 bits. obviamente, coldfusion y java jdk 1.6.45 no pueden manejar esto. El siguiente paso en el odysee fue pensar en instalar un proveedor de seguridad alternativo para Java, y decidí un castillo hinchable. ver también http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

Luego descargué el

bcprov-ext-jdk15on-156.jar

de http://www.bouncycastle.org/latest_releases.html y lo instaló en C: \ jdk6_45 \ jre \ lib \ ext o donde sea que esté su jdk, en la instalación original de coldfusion 8 estaría en C: \ JRun4 \ jre \ lib \ ext pero uso un jdk más nuevo (1.6.45) ubicado fuera del directorio de coldfusion. es muy importante poner bcprov-ext-jdk15on-156.jar en el directorio \ ext (esto me costó unas dos horas y algo de pelo ;-) luego edité el archivo C: \ jdk6_45 \ jre \ lib \ security \ java.security (¡con wordpad no con editor.exe!) y poner en una línea para el nuevo proveedor. luego la lista parecía

#
# 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

(ver el nuevo en la posición 1)

luego reinicie el servicio coldfusion por completo. entonces puedes

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

y disfruta la sensación ... y por supuesto

Qué noche y qué día. Esperemos que esto ayude (parcial o totalmente) a alguien por ahí. si tiene preguntas, solo envíeme un correo electrónico a info ... (dominio de arriba).

Raffael Meier
fuente
0

Si el servidor admite un cifrado que no incluye DH, puede obligar al cliente a seleccionar ese cifrado y evitar el error de DH. Como:

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

Tenga en cuenta que especificar un cifrado exacto es propenso a la rotura a largo plazo.

Jason Martin
fuente
0

Obtuvimos el mismo error de excepción exacto, para solucionarlo fue fácil después de horas navegando por Internet.

Descargamos la versión más alta de jdk que pudimos encontrar en oracle.com, la instalamos y señalamos el servidor de aplicaciones Jboss al directorio del nuevo jdk instalado.

¡Reinició Jboss, reprocesó, solucionó el problema!

Peter Azuka Molokwu
fuente
0

Tengo este error con Bamboo 5.7 + Gradle project + Apache. Gradle intentó obtener algunas dependencias de uno de nuestros servidores a través de SSL.

Solución:

  1. Generar parámetro DH:

con OpenSSL:

openssl dhparam 1024

salida de ejemplo:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. Agregar salida al archivo de certificado (para Apache - SSLCertificateFileparam)

  2. Reiniciar apache

  3. Reiniciar Bamboo

  4. Intenta construir el proyecto nuevamente

Evgeny Lebedev
fuente
0

Solía ​​tener un error similar al acceder a svn.apache.org con clientes SVN de Java utilizando un JDK de IBM. Actualmente, svn.apache.org utiliza las preferencias de cifrado de los clientes.

Después de ejecutar solo una vez con un paquete de captura / javax.net.debug = TODO pude poner en la lista negra solo un único cifrado DHE y las cosas funcionan para mí (ECDHE se negocia en su lugar).

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

Una buena solución rápida cuando no es fácil cambiar el cliente.

Covener
fuente
0

Recientemente tuve el mismo problema y después de actualizar la versión jdk de 1.6.0_45 a jdk1.7.0_191 que resolvió el problema.

Sam
fuente
-1

Para mí, la siguiente línea de comando solucionó el problema:

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

Estoy usando JDK 1.7.0_79

rico-chango
fuente
1
Me enfrenté a la misma situación usando JDK 1.7.0_xx. Por defecto, el problema se resolverá después de usar jdk 1.8. Pero a veces no podemos actualizar jdk rápidamente. Entonces, mi problema se resolvió después de agregar la configuración del sistema: System.setProperty ("https.protocols", "TLSv1.2"); System.setProperty ("despliegue.seguridad.TLSv1.2", "verdadero");
Ramgau