60

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!

ChrisianBartram
  • 733
  • 1
  • 5
  • 9
  • You probably need to provide more details. Using a self signed cert I assume? What java version? – D-Klotz Jul 05 '16 at 14:32
  • 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 – ChrisianBartram Jul 05 '16 at 14:41
  • 1
    (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. – dave_thompson_085 Jul 05 '16 at 21:47
  • 1
    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. – John Yeary Feb 02 '18 at 16:12

13 Answers13

68

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.

wwjih123
  • 1,076
  • 9
  • 7
  • thanks a lot! it saved me! Need to dig a little deeper about the reason why this was enabled..! – hakish Jan 29 '20 at 19:23
  • I think this is enabled with higher version of Java as security improvement? Not 100% sure. If someone know please confirm. – wwjih123 Jan 30 '20 at 20:02
  • 6
    I read it differently, this is disabling weak algorithms and you should used better ones. – Betlista Jan 31 '20 at 18:09
  • 9
    For Java 11+ the file is in "$JAVA_HOME/conf/security". – MinionAttack Apr 06 '21 at 15:21
  • 6
    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. – Oleg Kurbatov Apr 24 '21 at 09:42
  • 19
    @OlegKurbatov Thanks! It helps me in my issue. Per https://www.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. – zhongxiao37 Apr 26 '21 at 13:32
  • 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: https://stackoverflow.com/questions/67332909/why-can-java-not-connect-to-mysql-5-7-after-the-latest-jdk-update-and-how-should . I didn't find an optimal solution to that yet, since just tweaking the `java.security` file seems like a bad idea. – bersling Apr 30 '21 at 18:55
  • 3
    @wwjih123 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 help – Ankur Raiyani May 05 '21 at 08:52
  • 1
    This worked for me: JDK 17 on Windows 10 - Edited $JAVA_HOME/conf/security/java.security file and commented out both lines, as suggested. – Harry Mantheakis Dec 06 '21 at 15:23
39

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
informatik01
  • 16,038
  • 10
  • 74
  • 104
Rodney
  • 391
  • 3
  • 2
  • 4
    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? – bersling Apr 30 '21 at 09:27
  • I run in this problem on Centos 7 – Sérgio May 06 '21 at 09:32
  • 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. – Emily May 06 '21 at 16:31
  • 1
    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. – David Powell May 10 '21 at 01:23
  • Related https://bugs.openjdk.java.net/browse/JDK-8258597 – wpater May 13 '21 at 16:34
  • 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. – sunitkatkar Dec 05 '21 at 22:34
  • 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\security – gallo2000sv Jan 15 '22 at 20:17
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.

vbence
  • 20,084
  • 9
  • 69
  • 118
automaton
  • 1,091
  • 1
  • 9
  • 23
12

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

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

That fixed the problem for me.


Edit 04-02-2022:

As Yair's comment says:

Since Connector/J 8.0.28 enabledTLSProtocols has been renamed to tlsVersions.

Gerard de Visser
  • 7,590
  • 9
  • 50
  • 58
  • 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. – Jari Turkia Nov 10 '21 at 15:57
  • Works well for Amazon Aurora MySQL – kio21 Dec 30 '21 at 08:19
  • Since Since Connector/J 8.0.28 enabledTLSProtocols has been renamed to tlsVersions. See https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html – Yair Kukielka Feb 04 '22 at 10:48
  • @YairKukielka Thx for your comment. I've added it to the answer. – Gerard de Visser Feb 04 '22 at 11:11
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

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Peter
  • 99
  • 1
  • 2
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.

sari paisley
  • 61
  • 1
  • 3
  • 4
    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: https://www.oracle.com/java/technologies/javase/8u291-relnotes.html#JDK-8202343 – eidottermihi May 12 '21 at 14:52
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
Gray
  • 115,027
  • 24
  • 293
  • 354
3

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>
adlerer
  • 1,010
  • 11
  • 14
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.

Sergey Shcherbakov
  • 4,534
  • 4
  • 40
  • 65
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.

xKobalt
  • 1,498
  • 2
  • 13
  • 19
Cesc Canet
  • 83
  • 1
  • 8
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
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.

Yotta_Dev
  • 11
  • 4
0

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

DonMehdi
  • 11
  • 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 Review](/review/late-answers/30811030) – Procrastinator Jan 17 '22 at 08:15