¿Por qué Java no puede conectarse a MySQL 5.7 después de la última actualización de JDK y cómo debería solucionarse? (ssl.SSLHandshakeException: sin protocolo apropiado)

7 minutos de lectura

avatar de usuario
bersling

En la última actualización del JDK en abril de 2021 (11.0.11+9-0ubuntu2~18.04) apoyo para TLSv1 y TLSv1.1 se eliminó, presumiblemente porque desde marzo de 2021 esas versiones ya no son compatibles. Esto es evidente por la diferencia en el java.security expediente:

Antes:

jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \
    EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves

Después:

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves

que también se analiza en esta publicación SO: SSLHandShakeException No Appropriate Protocol . En ese hilo también hay más respuestas apareciendo en los últimos días desde la versión actualizada de JDK.

Después de esta actualización del JDK, recibimos el error

java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.

con c3p0.

Después de cambiar a hikari tenemos un error más significativo:

ERROR [2021-04-29 16:21:16,426] com.zaxxer.hikari.pool.HikariPool: HikariPool-1 - Exception during pool initialization.
! javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

Estamos ejecutando en MySQL 5.7.33-0ubuntu0.18.04.1. Ahora en mi entendimiento como se describe aquí, MySQL 5.7 es compatible con TLSv1.2. También al correr SHOW VARIABLES LIKE 'tls_version'; obtenemos TLSv1,TLSv1.1,TLSv1.2 que sugieren que TLSv1.2 esta apoyado.

Entonces, la pregunta es, ¿por qué JDK y MySQL simplemente no están de acuerdo en usar TLSv1.2 y qué podemos hacer al respecto, para que se comuniquen con TLSv1.2?

Nota: no creo que cambiar el java.security ¡El archivo como se sugiere en el otro hilo es una buena solución a largo plazo para este problema!

  • ¿Y cuál es la pregunta ahora? ¿Cómo hacer que Java acepte TLS 1.0 nuevamente o cómo hacer que MySQL use TLS 1.2? No me queda muy claro.

    – poco pegajoso

    30 de abril de 2021 a las 11:18

  • Gracias por la pista, reformulé la pregunta para que quede más clara. Creo que el objetivo debería ser usar TLSv1.2 como el camino a seguir.

    – bersling

    30 de abril de 2021 a las 11:25

  • Intente agregar ‘enabledTLSProtocols=TLSv1.2’ a la cadena de conexión de MySQL. Esto hará cumplir el protocolo TLSV1.2 para la conexión mysql de java y no tendrá que realizar ningún cambio en el archivo java.security.

    – skelwa

    4 de mayo de 2021 a las 8:05

  • Desde Connector/J 8.0.28, se cambió el nombre de enableTLSProtocols a tlsVersions. Ver dev.mysql.com/doc/conector-j/8.0/en/…

    – Yair Kukielka

    4 de febrero a las 10:52

avatar de usuario
kristianmitk

Como @skelwa ya comentó, deberá agregar el enabledTLSProtocols=TLSv1.2 propiedad de configuración en la cadena de conexión para resolver su problema.

Una cadena de conexión completa para Conector/J podría verse así:

jdbc:mysql://<host>:<port>/<dbname>?enabledTLSProtocols=TLSv1.2

Para r2dbc tendrás que usar tlsVersion=TLSv1.2 en cambio.

Para Conector/J v8.0.28 enabledTLSProtocols fue renombrado a tlsVersions (ver Nota). Sin embargo, el nombre original permanece como un alias.


La pregunta que queda es:

¿Por qué JDK y MySQL simplemente no están de acuerdo en usar TLSv1.2?

Aunque ambas partes realmente admiten TLSv1.2, el problema que estaba experimentando lo presenta el comportamiento predeterminado de Connector/J. Por motivos de compatibilidad, Connector/J no habilita TLSv1.2 y superior de forma predeterminada. Por lo tanto, uno tiene que habilitarlo explícitamente.

Ver lo siguiente Nota:

Para Connector/J 8.0.18 y versiones anteriores cuando se conecta a MySQL Community Server 5.6 y 5.7 mediante la API de JDBC: debido a problemas de compatibilidad con MySQL Server compilado con yaSSL, Connector/J no habilita las conexiones con TLSv1.2 y versiones posteriores de manera predeterminada. Al conectarse a servidores que restringen las conexiones para usar esas versiones superiores de TLS, habilítelos explícitamente configurando la propiedad de conexión Connector/J enableTLSProtocols (por ejemplo, establezca enableTLSProtocols=TLSv1,TLSv1.1,TLSv1.2).


ADVERTENCIA: Tenga en cuenta que soluciones sugiriendo editar jdk.tls.disabledAlgorithms dentro de jre/lib/security plantear un riesgo de seguridad a su aplicación y cambiar cualquier cosa allí podría tener implicaciones graves. Hay razones por las que esos protocolos se deshabilitaron y uno no debe simplemente eliminar todo o incluso solo partes de esa lista.


Nota: Si desea obtener más información de bajo nivel del JDK para depurar su problema, puede habilitar los registros de depuración de SSL pasando la siguiente configuración al comando Java:

-Djavax.net.debug=ssl,handshake

o incluso
-Djavax.net.debug=all

En tu caso verás algo como:

...(HANDSHAKE_FAILURE): Couldn't kickstart handshaking (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
    at java.base/sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:170)
    at java.base/sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:98)
    ...

  • gracias por la recomendación. solo quería agregar para intentar usar el último conector mysql recomendado j para el software que está utilizando. Estábamos probando con el conector mysql 5.1.42, así que intenté usar 5.1.48 y habilitar TLS v1.2 en la URL de jdbc y ¡funcionó! También usó opciones de Java -Djdk.tls.client.protocols=TLSv1.2,TLSv1.3 y en servidor tomcat.xml sslProtocol="TLS" sslEnabledProtocols="TLSv1.2,TLSv1.3". Asegúrese de leer también las notas de mysql aquí: dev.mysql.com/doc/conector-j/8.0/en/…

    – Savvas Radević

    29 de marzo a las 8:12


avatar de usuario
Ankur Raiyani

acabo de agregar usarSSL=falso Y funcionó para mí.

jdbc:mysql://<host>:<port>/<dbname>?useSSL=false

Tengo JDK 8, MySQL 5.7 y mysql-connector-java lib con la versión 5.1.38

Esto es útil cuando desea ejecutar rápidamente solo en un entorno local (no en preparación/prueba/producción)

  • En una DMZ, podría estar bien no tener cifrado en lugar de un cifrado débil. En producción por lo general no está bien.

    – sombrío

    2 de septiembre de 2021 a las 7:34

  • Título de la pregunta: “¿Cómo debería arreglarse? (ssl.SSLHandshakeException: No hay protocolo apropiado)” Su respuesta: Deshabilitar SSL

    – Josué Schlichting

    7 sep 2021 a las 14:49


  • Esto resuelto para mí. Solo usé esta opción porque estoy en un entorno de desarrollo local.

    – Vinicius

    14/10/2021 a las 21:42


  • que ventaja tiene useSSL=false proporcionar más enabledTLSProtocols=TLSv1.2 (respuesta aceptada)? No veo un beneficio, mientras que lo hace inseguro como una desventaja.

    – bersling

    14 abr a las 11:21

Vine aquí porque tenía el mismo problema, pero desafortunadamente,

jdbc:mysql://host:puerto/nombrebd?enabledTLSProtocols=TLSv1.2

no funcionó para mí porque estoy usando r2dbc. Después de un poco de depuración, descubrí que el nombre del parámetro debe ser tlsVersion en su lugar, por lo que puede utilizar, por ejemplo:

spring.r2dbc.url=r2dbc:mysql://host:port/dname?tlsVersion=TLSv1.2

  • Así es también como funciona después de Connector/J 8.0.28, enableTLSProtocols ha sido renombrado a tlsVersions. Ver dev.mysql.com/doc/conector-j/8.0/en/…

    – Yair Kukielka

    4 de febrero a las 10:50

Enfrenté este problema debido a la versión anterior de mysql-conector-java-5.1.40-bin.jar & OpenJDK 1.8 versión, después de actualizar a la versión 5.1.49 resolvió mi problema

Puedes hacer los siguientes pasos:

  1. Abra el archivo java.security. (Está en la carpeta jre/lib/security)
  2. Encuentra la siguiente línea: jdk.tls.disabledAlgorithms
  3. Comenta esa línea completa.

Después de esto, intente ejecutar y debería funcionar.

O si solo desea un algoritmo específico, elimínelo de la lista de deshabilitados.

Puede enviarlo en la configuración y comentarlo en el archivo java.security

jdbc:mysql://<host>:<port>/<dbname>?enabledTLSProtocols=TLSv1.2

  • Comentar “jdk.tls.disabledAlgorithms” es un consejo catastróficamente malo… Es un poco como decir: la forma más rápida de llegar al trabajo por la mañana es dejar las puertas del coche abiertas y las llaves puestas. La eliminación selectiva de elementos es solo un poco menos mala…

    – paulsm4

    1 de julio de 2021 a las 18:51


  • @ paulsm4 eso es cierto y no se recomienda fuera del entorno de desarrollo local.

    – VayujRajan

    5 de julio de 2021 a las 19:37

  • Recuerde: las cosas que hace en un entorno de desarrollo a menudo tienen la mala costumbre de filtrarse inadvertidamente a sus entornos ascendentes. Mejor consejo: “Solo di que no” 😉

    – paulsm4

    5 de julio de 2021 a las 19:58


  • Comentar “jdk.tls.disabledAlgorithms” es un consejo catastróficamente malo… Es un poco como decir: la forma más rápida de llegar al trabajo por la mañana es dejar las puertas del coche abiertas y las llaves puestas. La eliminación selectiva de elementos es solo un poco menos mala…

    – paulsm4

    1 de julio de 2021 a las 18:51


  • @ paulsm4 eso es cierto y no se recomienda fuera del entorno de desarrollo local.

    – VayujRajan

    5 de julio de 2021 a las 19:37

  • Recuerde: las cosas que hace en un entorno de desarrollo a menudo tienen la mala costumbre de filtrarse inadvertidamente a sus entornos ascendentes. Mejor consejo: “Solo di que no” 😉

    – paulsm4

    5 de julio de 2021 a las 19:58


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad