SSLHandShakeException No Appropriate Protocol
Asked Answered
A

13

62

I recently added SSL to my website and it can be accessed over https. Now when my java application tries to make requests to my website and read from it with a buffered reader it produces this stack trace

Im not using a self signed certificate the cert is from Namecheap who uses COMODO SSL as the CA to sign my certificate. im using java 8

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.Handshaker.activate(Handshaker.java:503)
at sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1482)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1351)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)

My code is very basic and simply tries to read the page on my site using a buffered reader

 private void populateDataList() {
    try {
        URL url = new URL("https://myURL.com/Data/Data.txt");
        URLConnection con = url.openConnection();
        con.setRequestProperty("Connection", "close");
        con.setDoInput(true);
        con.setUseCaches(false);

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String line;
        int i = 0;
        while((line = in.readLine()) != null) {
            this.url.add(i, line);
            i++;
        }
    }   catch (Exception e) {
        e.printStackTrace();
    }

}

Ive tried adding my SSL certificate to the JVM's Keystore and Ive also even tried to accept every certificate (which defeats the purpose of SSL I know) with this code

 private void trustCertificate() {
    TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
    };
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (GeneralSecurityException e) {
    }
    try {
        URL url = new URL("https://myURL.com/index.php");
        URLConnection con = url.openConnection();
        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String line;
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }

    } catch (Exception e) {

    }
}

Im stumped and any help would be much appreciated!

Aquilegia answered 5/7, 2016 at 14:24 Comment(4)
You probably need to provide more details. Using a self signed cert I assume? What java version?Alluring
Im not using a self signed certificate the cert is from Namecheap who uses COMODO SSL as the CA to sign my certificate. im using java 8Aquilegia
(1) The cert has nothing to do with this error. (2) Are you using the Sun/Oracle version of Java 8 and if so which update, or some other Java? Have any configuration changes been made in the JRE especially in the file $JRE/lib/security/java.security? (3) Do you have any system properties set invoving https especially https.protocols? (4) Try running with sysprop javax.net.debug=ssl and post the result, except that if your truststore has lots of certs (which the default does) you can chop that part down to a minimum.Suzettesuzi
Please indicate the Java version you are using. if you add -Djavax.net.debug=ssl:handshake:verbose it will allow you to examine the handshake issue in more detail.Pneumatometer
O
69

In $JRE/lib/security/java.security:

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

This line is enabled, after I commented out this line, everything is working fine. Apparently after/in jre1.8.0_181 this line is enabled.

My Java version is "1.8.0_201.

Ossifrage answered 30/7, 2019 at 14:21 Comment(10)
thanks a lot! it saved me! Need to dig a little deeper about the reason why this was enabled..!Prefrontal
I think this is enabled with higher version of Java as security improvement? Not 100% sure. If someone know please confirm.Ossifrage
I read it differently, this is disabling weak algorithms and you should used better ones.Aymer
For Java 11+ the file is in "$JAVA_HOME/conf/security".Enchanter
In case someone found that because of MySQL JDBC Driver error, you need to only exclude TLSv1 and TLSv1.1 from that list and it will work.Gentile
@OlegKurbatov Thanks! It helps me in my issue. Per oracle.com/java/technologies/javase/8u291-relnotes.html, the TLS 1.0 and 1.1 is disabled in last week's release JDK8-u292. Could you try to use enabledTLSProtocols=TLSv1.2 explicitly in your connection string? Hope it will also help you because TLSv1.0 and TLSv1.1 are deprecated.Grogshop
It is quite probable that you landed here because of the latest JDK release in April 2021, which disables TLSv1 and TLSv1.1 as mentioned by @zhongxiao37. Especially in conjunction with MySQL this seems to lead to a problem, see here: #67333409 . I didn't find an optimal solution to that yet, since just tweaking the java.security file seems like a bad idea.Maidservant
@Ossifrage Can you explain why this error appears suddenly? My solution was working fine till today with Tomcat9 & JDK8, I didn't make any changes and suddenly I started getting this error. Don't know why? Please helpBobstay
This worked for me: JDK 17 on Windows 10 - Edited $JAVA_HOME/conf/security/java.security file and commented out both lines, as suggested.Solidify
I removed the TLSv1 and TLSv1.1 and its working fine.Consultant
S
40

I also run into this with the Java8 update 1.8.0.229 on Ubuntu 18.04.

I changed the following part:

# Example:
#   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
#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

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

I removed TLSv1 and TLSv1.1 from the list of jdk.tls.disabledAlgorithms inside the file

/etc/java-8-openjdk/security/java.security

After checking this:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 5.7.33-0ubuntu0.18.04.1 (Ubuntu)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version';
+---------------+-----------------------+
| Variable_name | Value                 |
+---------------+-----------------------+
| tls_version   | TLSv1,TLSv1.1,TLSv1.2 |
+---------------+-----------------------+
1 row in set (0.00 sec)

mysql> exit
Swastika answered 28/4, 2021 at 12:23 Comment(7)
The problem also appears with the latest openjdk 11 versions (11.0.11+9-0ubuntu2~18.04). What I don't understand is, why don't java and mysql just agree on using TLSv1.2, since both parties seem to support it? Also, just patching the java.security file isn't a long term solution, what's the way forward with this issue?Maidservant
I run in this problem on Centos 7Tanning
Also using openjdk 11.0.11+9, same issue. Had to roll back to use an older openjdk image while trying to figure out a fix.Walleyed
Thank you so much for posting this. It fixed my issue! What I don't understand is why it became an issue in the first place - this has been running unchanged on a Raspberry Pi for a year or so with no changes.Strachan
Related bugs.openjdk.java.net/browse/JDK-8258597Dink
I had this problem with Java email program from a legacy Spring web app. First there was the issue of an antivirus blocking the call to smtp.gmail.com. So had to fix that and also install the smtp.gmail.com server ceritificate in the Java 8 keystore. Then had to follow this procedure of not disabling TLS protocols from java.security file. It all worked in the end! Thanks for this solution.Flattie
Fixed with this on windows 10 for a software that runs on Java and mysql server (Unicenta). Thanks a lot. File path on windows is: \ProgramFiles\Java\lib\securityCola
K
13

You can add the expected TLS protocol to your connection string like this:

jdbc:mysql://localhost:3306/database_name?enabledTLSProtocols=TLSv1.2

If you are using Connector/J 8.0.28 or newer, use:

jdbc:mysql://localhost:3306/database_name?tlsVersions=TLSv1.2
Koon answered 10/6, 2021 at 9:12 Comment(4)
In AWS RDS MariaDB, this does not work. By looking at the connection with Wireshark, it does proceed to the point where TLSv1 Record Layer: Alert (Level: Fatal, Description: Protocol Version) will be thrown. Without enabledTLSProtocols=TLSv1.2 connection is dropped at early stages.Phototherapy
Works well for Amazon Aurora MySQLBaculiform
Since Since Connector/J 8.0.28 enabledTLSProtocols has been renamed to tlsVersions. See dev.mysql.com/doc/connector-j/8.0/en/…Nike
@YairKukielka Thx for your comment. I've added it to the answer.Koon
H
12
protocol is disabled or cipher suites are inappropriate

The key to the problem lies in that statement. What it basically means is either:

  1. The TLS implementation used by the client does not support the cipher suites used by the server's certificate.
  2. The TLS configuration on the server has disabled cipher suites supported by the client.
  3. The TLS configurations on the client disable cipher suites offered by the server.
  4. TLS version incompatibility between the client and server.

This leads to handshake failure in TLS, and the connection fails. Check one or all of the three scenarios above.

Hallucinate answered 5/7, 2016 at 18:43 Comment(5)
This exception occurs even before sending to the server.Suzettesuzi
It appears to be occurring during the TLS handshake.Hallucinate
It's in the handshake logic, but if you trace through the code it's at a point before anything (in particular ClientHello) is sent at the socket=TCP level. (The TCP SYN/ACK has already been done, if you count that, but that isn't relevant to SSL/TLS.)Suzettesuzi
Yep i had to switch "SSL" with "TLS" in my setSecureSocketProtocol and it worked fineLuzluzader
where is setSecureSocketProtocolNoisette
S
9

In my case I am runnig Centos 8 and had the same issue with Imap/Java. Had to update the system-wide cryptographic policy level.

  1. update-crypto-policies --set LEGACY
  2. reboot machine.

Thats it.

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/considerations_in_adopting_rhel_8/security_considerations-in-adopting-rhel-8#tls-v10-v11_security

Sitar answered 24/6, 2020 at 8:26 Comment(2)
Thank you! This does solve my MySQL-connection problem.Phototherapy
Thank you. other solutions solved my local issue, but i was still facing the same problem in test server. this one fixed it.Theorize
H
6

We started experiencing this problem after upgrading to jre1.8.0_291. I commented out "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" in java.security located in C:\Program Files\Java\jre1.8.0_291\lib\security which resolved the problem.

Hypermetropia answered 28/4, 2021 at 18:21 Comment(1)
We experienced the same problem, but instead of fully commenting out the jdk.tls.disabledAlgorithms line in $JRE_HOME/lib/security/java.security we just removed TLSv1 and TLSv1.1 from the list, which was enough to fix the issue. This is also suggested by OpenJDK/Oracle here: oracle.com/java/technologies/javase/…Mythicize
D
5

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

For posterity, I recently bumped up against this using IBM's JDK8 implementation which specifically disables TLS1.1 and 1.2 by default (sic). If you want to see what TLS versions are supported by the JVM, run something like the following code:

SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
String[] supportedProtocols = context.getDefaultSSLParameters().getProtocols();
System.out.println(Arrays.toString(supportedProtocols));

The code spits out [TLSv1] by default under AIX JDK8. Not good. Under Redhat and Solaris it spits out [TLSv1, TLSv1.1, TLSv1.2].

I could not find any values in the java.security file to fix this issue but there might be some for your architecture. In the IBM specific case, we have to add:

-Dcom.ibm.jsse2.overrideDefaultTLS=true
Donyadoodad answered 4/1, 2021 at 22:41 Comment(1)
I tried with getInstance("TLSv1.2"), it returned [TLSv1.2] (J9 version 1.8.0_191)Perineuritis
M
4

In my case I had to upgrade the mysql client library to the latest version and it started working again:

    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>8.0.24</version>
    </dependency>
Malo answered 9/5, 2021 at 12:4 Comment(2)
I was on 8.0.16 and it appeared to work for me! Thank you for the idea! Spring boot app deployed to heroku was my circumstanceRiproaring
Upgraded my driver to 8.0.25, and that seems to have done the trick.Arieariel
H
2

I have encountered

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

error when accessing TLS 1.3 enabled endpoint from a Java 11 application. That is a usual case in GCP, for example.

The problem has gone away without any changes in my code just by upgrading from Java 11 to Java 14.

The Java 11 doesn't deprecate earlier TLS protocol versions by default. Instead of configuring it, simple upgrade of the runtime to Java 14 has helped.

Harday answered 22/1, 2021 at 8:37 Comment(0)
D
1

Apparently, if you have TLS 1.0 disabled the emails won't be sent out. TLS Versions 1.1 and 1.2 do not work. Peter's suggestion did the trick for me.

Donets answered 29/6, 2020 at 16:32 Comment(0)
C
1

I was face with the same situation on a tomcat7 server, 5.7.34-0ubuntu0.18.04.1, openjdk version "1.8.0_292"

I tried many approaches like disabling SSL in the server.xml file, changing the connection strings etc etc

but in the end all i did was to edit the file java.security with sudo nano /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/java.security

comment out and remove TLSv1 and TLSv1.1

# Comment the line below
#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

# your new line should read as beloew
jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves
Cappuccino answered 13/6, 2021 at 16:47 Comment(0)
A
0

For ME in this case :

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

I found that this is JDK/JRE (Java\jdk1.8.0_291\jre\lib\security) config related, and in order to solve it you need to Disable the TLS anon and NULL cipher suites.

You can found how to do this in the oficial documentation here: https://www.java.com/en/configure_crypto.html

Also before doing this, consider the implications of using LEGACY algorithms.

Astraddle answered 2/6, 2021 at 8:28 Comment(0)
Y
0

upgraded from 1 to 2 + modifying the $JRE/lib/security/java.security file did the trick. before after mysql driver

Yolondayon answered 13/1, 2022 at 15:49 Comment(1)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewAllargando

© 2022 - 2025 — McMap. All rights reserved.