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.
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.openssl
salida en la pregunta: "Cipher es DHE-RSA-AES256-SHA, la clave pública del servidor es 2048 bit". Y 2048> 1024 :-).Server public key (size)
fue, y es, la clave en el certificado.s_client
en 2011 no mostró clave efímera en absoluto; 1.0.2 en 2015 y hasta haceServer Temp Key
varias 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.Respuestas:
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.
fuente
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:
bcprov-jdk15on-154.jar
bcprov-ext-jdk15on-154.jar
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
fuente
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:
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_.
Finalmente, así es como se usa (certFilePath si la ruta del certificado se guardó desde openssl):
fuente
jdk.tls.disabledAlgorithms=DHE, ECDHE
en elJDK_HOME/jre/lib/security/java.security
que también trabaja y evitar todo este código.jdk.tls.disabledAlgorithms=DHE
. Usando 1.7.0_85-b15.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:
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):
Asqueroso.
fuente
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
.fuente
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());
fuente
Esta es una publicación bastante antigua, pero si usa Apache HTTPD, puede limitar el tamaño de DH. Ver http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh
fuente
Si está utilizando jdk1.7.0_04, actualice a jdk1.7.0_21. El problema se ha solucionado en esa actualización.
fuente
Es posible que tenga dependencias incorrectas de Maven. Debe encontrar estas bibliotecas en la jerarquía de dependencia de Maven:
Si tiene estas dependencias, ese es el error, y debe hacer esto:
Agregue la dependencia:
Excluir estas dependencias del artefacto que incluía las dependencias incorrectas, en mi caso es:
fuente
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.
fuente
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
mando. Alternativamente, puede usar los siguientes parámetros DH estándar de 1024 bits de RFC 2409, sección 6.2:
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.
fuente
Tengo el mismo problema con el servidor Yandex Maps, JDK 1.6 y Apache HttpClient 4.2.1. El error fue
con depuración habilitada por
-Djavax.net.debug=all
había un mensaje en un registroHe solucionado este problema agregando la biblioteca BouncyCastle
bcprov-jdk16-1.46.jar
y registrando un proveedor en una clase de servicio de mapasUn proveedor se registra en el primer uso de
MapService
.fuente
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 -i
no era suficiente.La instalación de JDK 7 solo tendrá éxito con la
rpm -U
opción de actualización como se ilustra a continuación.1. Descargar JDK 7
2. La instalación de RPM falla
3. La actualización de RPM tiene éxito
4. Confirme la nueva versión.
fuente
Resolvió el problema actualizando a JDK 8.
fuente
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
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
y consiguió
y
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
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
(ver el nuevo en la posición 1)
luego reinicie el servicio coldfusion por completo. entonces puedes
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).
fuente
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:
Tenga en cuenta que especificar un cifrado exacto es propenso a la rotura a largo plazo.
fuente
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!
fuente
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:
con OpenSSL:
salida de ejemplo:
Agregar salida al archivo de certificado (para Apache -
SSLCertificateFile
param)Reiniciar apache
Reiniciar Bamboo
Intenta construir el proyecto nuevamente
fuente
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).
Una buena solución rápida cuando no es fácil cambiar el cliente.
fuente
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.
fuente
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
fuente