57
votes

Pourquoi Java ne peut-il pas se connecter à MySQL 5.7 après la dernière mise à jour JDK et comment devrait-il être corrigé? (ssl.sslhandshakeException: pas de protocole approprié)

Dans la dernière mise à jour du JDK en avril 2021 ( 11.0.11 + 9-0ubuntu2 ~ 18.04 ) Prise en charge de tlsv1 et tlsv1.1 / Code> a été abandonné, probablement parce que depuis mars 2021, ces versions ne sont plus prises en charge. Cela est évident par le diff dans le fichier java.security :

avant:

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)

après:

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

qui est également discuté dans ce post SO: sslhandshakeException pas protocole approprié . Dans ce fil, il y a aussi plus de réponses qui apparaissent ces derniers jours depuis la version JDK mise à jour.

Après cette mise à jour du JDK, nous avons reçu l'erreur

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

avec c3p0 .

Après le passage à Hikari , nous avons eu une erreur plus significative:

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

Nous exécutons sur mysql 5.7.33-0ubuntu0.18.04.1 . Maintenant, dans ma compréhension, comme décrit ici , MySQL 5.7 prend en charge TLSV1.2. De plus, lors de l'exécution de , affichez des variables comme 'TLS_Version'; , nous obtenons tlsv1, tlsv1.1, tlsv1.2 qui suggèrent que tlsv1.2 est pris en charge .

Alors, la question est de savoir pourquoi le JDK et MySQL ne sont-ils pas d'accord sur l'utilisation de tlsv1.2 et que pouvons-nous faire à ce sujet, pour les faire communiquer avec tlsv1.2

?

Remarque: Je ne pense pas que changer le fichier java.security comme suggéré dans l'autre thread est une bonne solution à long terme pour ce problème!


4 commentaires

Et quelle est la question maintenant? Comment faire en sorte que Java accepte à nouveau TLS 1.0 ou comment faire en sorte que MySQL utilise TLS 1.2? Ce n'est pas vraiment clair pour moi.


Merci pour l'indice, j'ai reformulé la question pour le rendre plus claire. Je pense que l'objectif devrait être d'utiliser TLSV1.2 comme voie à suivre.


Essayez d'ajouter 'ENTIVETTLSPROTOCOLS = TLSV1.2' à la chaîne de connexion MySQL. Cela appliquera le protocole TLSV1.2 pour la connexion MySQL de Java et vous n'auriez pas à modifier le fichier java.security.


Depuis Connector / J 8.0.28, ENableDTLSProtoCols a été renommé TLSVersions. Voir dev.mysql.com /doc/connector-j/8.0/en/…


5 Réponses :


96
votes

Comme @skelwa a déjà commenté, vous devrez ajouter la enabledTlsprotoCols = tlsv1.2 propriété de configuration dans la chaîne de connexion pour résoudre votre problème.

Une chaîne de connexion complète pour connecteur / j pourrait ressembler à ceci:

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

Pour r2dbc Vous devrez utiliser tlsversion = tlsv1.2 à la place.

pour connecteur / j v8.0.28 activéstlsprotocols a été renommé tlsversions (voir note ). Cependant, le nom d'origine reste un alias.


La question qui reste est:

Pourquoi le JDK et MySQL ne sont-ils pas simplement d'accord sur l'utilisation Tlsv1.2 ?

Bien que les deux parties prennent en charge TLSV1.2, le problème que vous rencontrez est introduit par le comportement par défaut du connecteur / j. Pour les raisons de compatibilité, Connector / J n'activent pas TLSV1.2 et plus par défaut. Par conséquent, il faut l'activer explicitement.

Voir les suivants Remarque :

pour le connecteur / J 8.0.18 et plus tôt lors de la connexion à la communauté MySQL Serveur 5.6 et 5.7 en utilisant l'API JDBC: en raison de problèmes de compatibilité Avec MySQL Server compilé avec YASSL, Connector / J ne permet pas Connexions avec TLSV1.2 et plus par défaut. Lors de la connexion à des serveurs qui restreignent les connexions pour utiliser ces versions TLS supérieures, leur activer explicitement en définissant la propriété Connector / J Connexion activédTlsprotoCols (par exemple, définir activédTlsprotoCols = tlsv1, tlsv1.1, tlsv1.2).


AVERTISSEMENT: Veuillez noter que Solutions Strike> suggérant l'édition jdk.tls.disabledalgorithms à l'intérieur de JRE / lib / security pose un risque de sécurité à votre application et modifier tout ce qui pourrait avoir de graves implications! Il y a des raisons pour lesquelles ces protocoles ont été désactivés et il ne faut pas simplement supprimer tout ou même simplement des pièces de cette liste.


Remarque: si vous souhaitez obtenir plus de bas niveau Insignes du JDK pour déboguer votre problème, vous pouvez activer les journaux de débogage SSL en passant la configuration suivante au Java Comand:

-djavax.net.debug = SSL, Handshake ou même -djavax.net.debug = tout

Dans votre cas, vous verrez quelque chose comme:

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


1 commentaires

Merci pour la recommandation. Je voulais juste ajouter pour essayer également d'utiliser le dernier connecteur MySQL Recommandé J pour le logiciel que vous utilisez. Nous testions avec MySQL Connector 5.1.42, j'ai donc juste essayé d'utiliser 5.1.48 et d'activer TLS v1.2 dans l'URL JDBC et cela a fonctionné! A également utilisé des options Java -djdk.tls.client.protocols = tlsv1.2, tlsv1.3 et dans tomcat server.xml sslprotocol = "tls" ssleNabledProtoCols = "tlsv1.2, tlsv1. 3 ". Assurez-vous de lire également les notes MySQL ici: dev.mysql.com/doc/connector-j/8.0/en/…



-6
votes

Vous pouvez effectuer les étapes suivantes:

  • Ouvrez le fichier Java.Security. (Il est sous le dossier JRE / Lib / Security)
  • Trouvez la ligne suivante: jdk.tls.disabledalgorithms
  • Commentez cette ligne complète.
  • Après cette essai en cours d'exécution et cela devrait fonctionner.

    ou si vous voulez que seul un algorithme spécifique, supprimez-le de la liste désactivée.

    Vous pouvez l'envoyer en config et Commentez cela dans Java.Security Fichier

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


    3 commentaires

    Commentaire "Jdk.tls.disabledalgorithms" est catastrophiquement des conseils ... c'est un peu comme dire: le moyen le plus rapide de se rendre au travail le matin est de laisser les portes de votre voiture déverrouillées et les clés dans l'allumage. La suppression sélective des articles n'est que légèrement moins mauvaise ...


    @ PaulSm4 qui est vrai et non encouragé en dehors de l'environnement du développement local.


    N'oubliez pas: les choses que vous faites dans un environnement de développement ont souvent une mauvaise habitude de fuir par inadvertance dans vos environnements en amont. Meilleur conseil: "Dites simplement non";)



    12
    votes

    Je viens d'ajouter usessl = false et cela a fonctionné pour moi.

    jdbc: mysql: // : / ? usessl = false

    J'ai JDK 8, MySQL 5.7 et MySQL-Connector-Java Lib avec la version 5.1.38

    Ceci est utile lorsque vous souhaitez exécuter rapidement dans l'environnement local (pas de mise en scène / test / prod)


    4 commentaires

    Dans un DMZ, il pourrait être OK de ne pas avoir de cryptage au lieu d'un chiffrement faible. En production, ce n'est généralement pas OK.


    Titre de la question: "Comment doit-il être corrigé? (SSL.SSLhandshakeException: pas de protocole approprié)" Votre réponse: Désactiver SSL


    Cela a résolu pour moi. Je n'ai utilisé cette option que parce que je suis sur un environnement de développement local.


    Quel avantage usessl = false fournit activéstlsprotocols = tlsv1.2 (réponse acceptée)? Je ne vois pas d'avantages, alors que cela le rend peu sûr comme un inconvénient?



    3
    votes

    Je suis venu ici parce que j'avais le même problème, mais malheureusement,

    jdbc: mysql: // hôte: port / dbname? EntablettlsprotoCols = tlsv1.2

    n'a pas fonctionné pour moi parce que j'utilise R2DBC. Après un peu de débogage, j'ai découvert que le nom du paramètre doit être tlsversion à la place, vous pouvez donc utiliser, par exemple:

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


    1 commentaires

    C'est également ainsi que cela fonctionne après que Connector / J 8.0.28, ALBILDTLSPROTOCOLS a été renommé TLSVersions. Voir dev.mysql.com /doc/connector-j/8.0/en/…



    1
    votes

    J'ai fait face à ce numéro en raison de l'ancienne version de mysql-connector-java-5.1.40-bin.jar & openjdk 1.8 , après la mise à niveau vers la version 5.1.49, j'ai résolu mon problème < / p>


    0 commentaires