Why can Java not connect to MySQL 5.7 after the latest JDK update and how should it be fixed? (ssl.SSLHandshakeException: No appropriate protocol)

We Are Going To Discuss About Why can Java not connect to MySQL 5.7 after the latest JDK update and how should it be fixed? (ssl.SSLHandshakeException: No appropriate protocol). So lets Start this Java Article.

Why can Java not connect to MySQL 5.7 after the latest JDK update and how should it be fixed? (ssl.SSLHandshakeException: No appropriate protocol)

  1. Why can Java not connect to MySQL 5.7 after the latest JDK update and how should it be fixed? (ssl.SSLHandshakeException: No appropriate protocol)

    Although both parties do actually support TLSv1.2, the problem you were experiencing is introduced by the default behavior of Connector/J. For compatibility reasons Connector/J does not enable TLSv1.2 and higher by default. Therefore, one has to enable it explicitly.

  2. Java not connect to MySQL 5.7 after the latest JDK update and how should it be fixed? (ssl.SSLHandshakeException: No appropriate protocol)

    Although both parties do actually support TLSv1.2, the problem you were experiencing is introduced by the default behavior of Connector/J. For compatibility reasons Connector/J does not enable TLSv1.2 and higher by default. Therefore, one has to enable it explicitly.

Solution 1

As @skelwa already commented you will need to add the enabledTLSProtocols=TLSv1.2 configuration property in the connection string to resolve your issue.

A complete connection string for Connector/J could look like this:

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

For r2dbc you will need to use tlsVersion=TLSv1.2 instead.

For Connector/J v8.0.28 enabledTLSProtocols was renamed to tlsVersions (see note). However, the original name remains as an alias.


The question that remains is:

Why don’t the JDK and MySQL just agree on using TLSv1.2?

Although both parties do actually support TLSv1.2, the problem you were experiencing is introduced by the default behavior of Connector/J. For compatibility reasons Connector/J does not enable TLSv1.2 and higher by default. Therefore, one has to enable it explicitly.

See the following note:

For Connector/J 8.0.18 and earlier when connecting to MySQL Community
Server 5.6 and 5.7 using the JDBC API: Due to compatibility issues
with MySQL Server compiled with yaSSL, Connector/J does not enable
connections with TLSv1.2 and higher by default. When connecting to
servers that restrict connections to use those higher TLS versions,
enable them explicitly by setting the Connector/J connection property
enabledTLSProtocols (e.g., set
enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2).


WARNING: please be aware that solutions suggesting editing jdk.tls.disabledAlgorithms inside of jre/lib/security pose a security risk to your application and changing anything there might have severe implications!
There are reasons why those protocols were disabled and one should not simply remove everything or even just parts from that list.


Note: if you want to get more low level insights from the JDK to debug your problem you can enable ssl debug logs by passing the following configuration to the java comand:

-Djavax.net.debug=ssl,handshake
or even
-Djavax.net.debug=all

In your case you will see something like:

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

Original Author Of This Content

Solution 2

I just added useSSL=false and it worked for me.

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

I have JDK 8, MySQL 5.7 and mysql-connector-java lib with version 5.1.38

This is useful when you want to execute quickly in local environment only (not staging/test/prod)

Advertisements

Original Author Of This Content

Solution 3

I came here because I had the same issue, but unfortunately,

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

didn’t work for me because I’m using r2dbc. After a little bit of debugging I found out the name of the parameter must be tlsVersion instead, so you can use, for example:

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

Original Author Of This Content

Solution 4

You can do the following steps:

  1. Open java.security file. (It is under jre/lib/security folder)
  2. Find the following line : jdk.tls.disabledAlgorithms
  3. Comment that complete line.

After this try running and it should work.

Or if you want only specific algorithm remove it from disabled list.

You can send it in config and comment that in java.security file

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

Original Author Of This Content

Conclusion

Advertisements

So This is all About This Tutorial. Hope This Tutorial Helped You. Thank You.

Also Read,

Siddharth

I am an Information Technology Engineer. I have Completed my MCA And I have 4 Year Plus Experience, I am a web developer with knowledge of multiple back-end platforms Like PHP, Node.js, Python and frontend JavaScript frameworks Like Angular, React, and Vue.

Leave a Comment