361

With the two classes below, I've tried connect to a MySQL database. However, I always get this error:

Wed Dec 09 22:46:52 CET 2015 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

This is the test class with the main method:

public class TestDatabase {

    public static void main(String[] args) {
        Database db = new Database();
        try {
            db.connect();
        } catch (Exception e) {
            e.printStackTrace();
        }
        db.close();
    }
}

This is the Database class:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Database {

    private Connection con;

    public void connect() throws Exception{

        if(con != null) return;

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new Exception("No database");
        }

        String connectionURL = "jdbc:mysql://localhost:3306/Peoples";

        con = DriverManager.getConnection(connectionURL, "root", "milos23");        
    }

    public void close(){
        if(con != null){
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
Nick
  • 138,499
  • 22
  • 57
  • 95
Milos86
  • 3,621
  • 3
  • 12
  • 5

19 Answers19

642

Your connection URL should look like the below,

jdbc:mysql://localhost:3306/Peoples?autoReconnect=true&useSSL=false

This will disable SSL and also suppress the SSL errors.

Joel Christophel
  • 2,604
  • 4
  • 30
  • 49
Priyank Gosalia
  • 6,633
  • 1
  • 10
  • 3
  • upvoted. But the URL string should now end with semicolon. – DevilInDisguise Feb 05 '16 at 14:46
  • 9
    in tomcat context file jdbc:mysql://localhost:3306/databaseName?autoReconnect=true;useSSL=false; – Amith Feb 11 '16 at 14:17
  • I don't know about Tomcat, but in reference to the method used in the OP's code, the semicolon at the end will cause a connection error and must be removed. Tested using mysql connecter 5.1.38 and JVM v1.7.0_79. – James Jensen Apr 13 '16 at 15:00
  • 28
    The confusion with semicolon is possibly due to the fact that in XML configuration you need to have it as ?autoReconnect=true&useSSL=false. Otherwise the parser thinks that you have some weird entity that you have to end with ';' – Bostone Jul 29 '16 at 22:21
  • 31
    I had same issue in hibernate but resolved by URL like this: `jdbc:mysql://localhost:3306/Peoples?autoReconnect=true&useSSL=false` I used **&** instead of **&** – Saqib Ahmed Apr 18 '17 at 06:44
  • disabling ssl is not a good idea, disabling the certificate verification will do less harm. – C.Vergnaud Oct 23 '18 at 08:16
  • how to specify this property for cloud fondry – legend Apr 22 '19 at 13:08
  • 3
    @Rogerthat there are cases for disabling SSL if the network is secure. For example I have SQL servers running in containers only accessed by clients on the same physical hardware. – Rodney Apr 23 '19 at 08:09
  • `useSSL` is deprecated, please use `sslModel=DISABLED`. See https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-security.html – zhongxiao37 Apr 26 '21 at 13:38
  • Going to plaintext is a highly retrograde step. He should *enable* SSL and ensure the truststores are correct, as recommended in the error message. – user207421 Aug 15 '23 at 23:29
147

How about using SSL but turning off server verification (such as when in development mode on your own computer):

jdbc:mysql://localhost:3306/Peoples?verifyServerCertificate=false&useSSL=true
Peter DeGregorio
  • 1,729
  • 1
  • 11
  • 5
38

The defaults for initiating a connection to a MySQL server were changed in the recent past, and (from a quick look through the most popular questions and answers on stack overflow) the new values are causing a lot of confusion. What is worse is that the standard advice seems to be to disable SSL altogether, which is a bit of a disaster in the making.

Now, if your connection is genuinely not exposed to the network (localhost only) or you are working in a non-production environment with no real data, then sure: there's no harm in disabling SSL by including the option useSSL=false.

For everyone else, the following set of options are required to get SSL working with certificate and host verification:

  • useSSL=true
  • sslMode=VERIFY_IDENTITY
  • trustCertificateKeyStoreUrl=file:path_to_keystore
  • trustCertificateKeyStorePassword=password

As an added bonus, seeing as you're already playing with the options, it is simple to disable the weak SSL protocols too:

  • enabledTLSProtocols=TLSv1.2

Example

So as a working example you'll need to follow the following broad steps:

First, make sure you have a valid certificate generated for the MySQL server host, and that the CA certificate is installed onto the client host (if you are using self-signed, then you'll likely need to do this manually, but for the popular public CAs it'll already be there).

Next, make sure that the java keystore contains all the CA certificates. On Debian/Ubuntu this is achieved by running:

update-ca-certificates -f
chmod 644 /etc/ssl/certs/java/cacerts

Then finally, update the connection string to include all the required options, which on Debian/Ubuntu would be something a bit like (adapt as required):

jdbc:mysql://{mysql_server}/confluence?useSSL=true&sslMode=VERIFY_IDENTITY&trustCertificateKeyStoreUrl=file%3A%2Fetc%2Fssl%2Fcerts%2Fjava%2Fcacerts&trustCertificateKeyStorePassword=changeit&enabledTLSProtocols=TLSv1.2&useUnicode=true&characterEncoding=utf8

Reference: https://beansandanicechianti.blogspot.com/2019/11/mysql-ssl-configuration.html

Buffoonism
  • 1,669
  • 11
  • 11
  • 3
    Not only this is the right answer, but it's also the most detailed and secure. If you get a warning on SSL, you should never skip it (except sandbox and local installations). You pointed me to the right solution for a Kubernetes Keycloack 9.0.2 cluster connecting to Azure MySQL. Thanks a lot! – iakko Apr 09 '20 at 17:03
30

Mention the url like:

jdbc:mysql://hostname:3306/hibernatedb?autoReconnect=true&useSSL=false

But in xml configuration when you mention & sign, the IDE shows below error:

The reference to entity "useSSL" must end with the ';' delimiter.

And then you have to explicitly use the & instead of & to be determined as & by xml thereafter in xml you have to give the url in xml configuration like this:

<property name="connection.url">jdbc:mysql://hostname:3306/hibernatedb?autoReconnect=true&amp;useSSL=false</property>
ArifMustafa
  • 4,617
  • 5
  • 40
  • 48
  • @caot for the comment about the ampersand and how to write it in the connection string, thank you – qualebs Sep 19 '20 at 03:32
23

An alternative method would be:

    Properties properties = new Properties();
    properties.setProperty("user", "root");
    properties.setProperty("password", "milos23");
    properties.setProperty("useSSL", "false");

    try (Connection conn = DriverManager.getConnection(connectionUrl, properties)) {
    ...
    } catch (SQLException e) {
    ...
    }
Yvan
  • 2,539
  • 26
  • 28
Jon
  • 555
  • 5
  • 10
12

Use this to solve the problem in hive while making connection with MySQL

<property>
   <name>javax.jdo.option.ConnectionURL</name>
   <value>jdbc:mysql://localhost/metastore?createDatabaseIfNotExist=true&amp;autoReconnect=true&amp;useSSL=false</value>
   <description>metadata is stored in a MySQL server</description>
</property>
Nagendra
  • 3
  • 1
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
  • But why doesn't it take with the **and** operator? I had something like `jdbc:mysql://localhost/metastore?useSSL=false&createDatabaseIfNotExist=true`. Without the and it works fine. – Kulasangar Jun 20 '17 at 04:19
  • 1
    for me the posted value worked smoothly, so I will flag this as a answer in end dec month of 2017 and working with hive-2.1.1 hive-site.xml. – ArifMustafa Dec 16 '17 at 09:08
  • 1
    I added/replaced this property in my hive-site.xml and it worked for me. – Amit Kumar Jun 18 '21 at 12:59
12

I found this warning too then I fixed it by using SSL=false suffix to the connection string like this example code.

Example:

connectionString = "jdbc:mysql://{server-name}:3306/%s?useUnicode=yes&characterEncoding=UTF-8&useSSL=false"
KHACHORNCHIT
  • 2,222
  • 23
  • 19
10

you need to user your mysql path like this:

<property name="url" value="jdbc:mysql://localhost:3306/world?useSSL=true"/>
Antoine
  • 800
  • 3
  • 14
  • 29
harun ugur
  • 1,718
  • 18
  • 18
9

This was OK for me:

this.conn = (Connection)DriverManager
    .getConnection(url + dbName + "?useSSL=false", userName, password);
simhumileco
  • 31,877
  • 16
  • 137
  • 115
Tomal
  • 91
  • 2
  • 3
9

To disable the warning while connecting to a database in Java, use the below concept −

autoReconnect=true&useSSL=false

Just need to change connectionURL like :

String connectionURL = jdbc:mysql://localhost:3306/Peoples?autoReconnect=true&useSSL=false

This will disable SSL and also suppress the SSL errors.

naib khan
  • 928
  • 9
  • 16
6

I use this property for hibernate in config xml

<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/bookshop?serverTimezone=UTC&amp;useSSL=false
</property>

without - serverTimezone=UTC - it doesn't work

Alexandr Kovalenko
  • 934
  • 1
  • 12
  • 13
4

Solution To fix it, append a useSSL=false at the end of the MySQL connection string :

ex.

application.properties

mysql datasource

spring.datasource.url=jdbc:mysql://localhost/dbname?useSSL=false
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
Community
  • 1
  • 1
Pravin Bansal
  • 4,315
  • 1
  • 28
  • 19
3

Per https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-security.html, sslMode property replaced the deprecated legacy properties useSSL, requireSSL, and verifyServerCertificate. So, you could use the connection string sslMode=DISABLED.

zhongxiao37
  • 977
  • 8
  • 17
  • It's not "sslModel", but "sslMode".However, the change occured with MySQL version 8.0.13. Extra-info: https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html – Tinel Barb Mar 17 '23 at 09:13
2

the new versions of mysql-connector establish SSL connection by default ...to solve it:

Download the older version of mysql-connector such as mysql-connector-java-5.0.8.zip

. . or . . Download OpenSSL for Windows and follow the instructions how to set it

Ahmad.ak
  • 93
  • 6
2

As of 8.0.13 the useSSL parameter is now deprecated and you should use sslMode:

MySQL :: MySQL Connector/J 8.0 Developer Guide :: 6.3.5 Security

sslMode

By default, network connections are SSL encrypted; this property permits secure connections to be turned off, or a different levels of security to be chosen. The following values are allowed: "DISABLED" - Establish unencrypted connections; "PREFERRED" - (default) Establish encrypted connections if the server enabled them, otherwise fall back to unencrypted connections; "REQUIRED" - Establish secure connections if the server enabled them, fail otherwise; "VERIFY_CA" - Like "REQUIRED" but additionally verify the server TLS certificate against the configured Certificate Authority (CA) certificates; "VERIFY_IDENTITY" - Like "VERIFY_CA", but additionally verify that the server certificate matches the host to which the connection is attempted.

This property replaced the deprecated legacy properties "useSSL", "requireSSL", and "verifyServerCertificate", which are still accepted but translated into a value for "sslMode" if "sslMode" is not explicitly set: "useSSL=false" is translated to "sslMode=DISABLED";

Unknown macro: {"useSSL=true", "requireSSL=false", "verifyServerCertificate=false"} is translated to "sslMode=PREFERRED";

Unknown macro: {"useSSL=true", "requireSSL=true", "verifyServerCertificate=false"} is translated to "sslMode=REQUIRED";

Unknown macro: {"useSSL=true" AND "verifyServerCertificate=true"} is translated to "sslMode=VERIFY_CA". There is no equivalent legacy settings for "sslMode=VERIFY_IDENTITY". Note that, for ALL server versions, the default setting of "sslMode" is "PREFERRED", and it is equivalent to the legacy settings of "useSSL=true", "requireSSL=false", and "verifyServerCertificate=false", which are different from their default settings for Connector/J 8.0.12 and earlier in some situations. Applications that continue to use the legacy properties and rely on their old default settings should be reviewed.

The legacy properties are ignored if "sslMode" is set explicitly. If none of "sslMode" or "useSSL" is set explicitly, the default setting of "sslMode=PREFERRED" applies.

Default Value PREFERRED Since Version 8.0.13

Pyroseza
  • 111
  • 1
  • 2
1

Since I am currently in development mode I set useSSL to No not in tomcat but in mysql server configurations. Went to Manage Access Settings\Manage Server Connections from workbench -> Selected my connection. Inside connection tab went to SSL tab and disabled the settings. Worked for me.

0

Please update your mysql connector. That will help.

0

If your connection is genuinely exposed to the network or you are working in a production environment with real data, then sure: we shouldn't be disabling SSL by including the option useSSL=false.

Try to update the JDBC connection string to include the latest protocol version as foloowing: jdbc:mysql://:/?enabledTLSProtocols=TLSv1.2

We have to explicitly mention the type of TLS protocol while establishing the DB connection in JDK 11.

Abhiram S
  • 94
  • 1
  • 12
0

Simply use Platform Independent zip or tar https://dev.mysql.com/downloads/connector/j/?os=26

Jackson
  • 71
  • 1
  • 6