连接MySQL数据库时SSL连接的警告提示

361

使用以下两个类,我尝试连接到MySQL数据库。但是,我总是会收到此错误消息:

Wed Dec 09 22:46:52 CET 2015 WARN: 建议不要在没有服务器身份验证的情况下建立SSL连接。根据MySQL 5.5.45+、5.6.26+和5.7.6+的要求,如果没有显式设置选项,则必须默认建立SSL连接。为了符合不使用SSL的现有应用程序,将verifyServerCertificate属性设置为“false”。您需要通过设置useSSL=false来明确禁用SSL,或者设置useSSL=true并提供信任存储来进行服务器证书验证。

这是带有main方法的测试类:

public class TestDatabase {

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

这是 Database 类:

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();
            }
        }
    }
}

3
谢谢回复,没关系,我只是不知道我需要在我的字符串连接URL的末尾加上ssl=true或false。 - Milos86
谢谢,那么新的connectionURL怎么样了? - user3290180
5
不是错误,而是警告。 - Fernando Silveira
自2006年以来,Class.forName("com.mysql.jdbc.Driver")这行代码就不再需要了。 - user207421
19个回答

643

您的连接URL应该像以下内容一样:

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

这将禁用SSL并抑制SSL错误。


42
在 JDBC 连接字符串中,不应以分号结尾。 - Amith
9
在Tomcat的上下文文件中: jdbc:mysql://localhost:3306/databaseName?autoReconnect=true;useSSL=false; - Amith
28
分号的混淆可能是因为在XML配置中,你需要将其写作?autoReconnect=true&useSSL=false。否则解析器会认为你有一些奇怪的实体需要以分号结尾。 - Bostone
31
我在使用Hibernate时遇到了同样的问题,但通过以下这个URL解决了:jdbc:mysql://localhost:3306/Peoples?autoReconnect=true&useSSL=false我使用了 & 而不是 **&**。 - Saqib Ahmed
3
@Rogerthat,如果网络是安全的,有时需要禁用SSL。例如,我有在容器中运行的SQL服务器,只能由同一物理硬件上的客户端访问。 - Rodney
显示剩余6条评论

147

使用SSL但关闭服务器验证如何(例如在自己的计算机上开发模式时):

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

2
这是我需要在IntelliJ / DataGrip上执行的操作,以通过SSL连接到MySQL数据库。 - Swaraj
那正是他不应该做的。阅读错误信息。 - user207421

38

最近,连接到MySQL服务器的默认值已更改,并且(根据在Stack Overflow上最受欢迎的问题和答案的快速查看)新值引起了很多困惑。更糟糕的是,标准建议似乎是完全禁用SSL,这可能会造成一些灾难。

现在,如果您的连接确实不会暴露于网络(仅限本地主机),或者您正在非生产环境中使用没有真实数据的情况,那么可以通过包括选项useSSL=false来禁用SSL而没有危害。

对于其他所有人,要使SSL与证书和主机验证正常工作,需要以下一组选项:

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

作为额外的奖励,既然您已经在使用选项,那么也很容易禁用弱SSL协议:

  • enabledTLSProtocols=TLSv1.2

示例

因此,作为一个工作示例,您需要按照以下广泛步骤:

首先,请确保为MySQL服务器主机生成了有效证书,并且CA证书已安装到客户机主机上(如果您正在使用自签名,则可能需要手动执行此操作,但对于流行的公共CA,它已经存在)。

接下来,请确保Java keystore包含所有CA证书。在Debian/Ubuntu上,可以通过运行以下命令来实现:

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

最后,更新连接字符串以包含所有所需的选项,对于Debian / Ubuntu来说,可能会像这样(根据需要进行调整):

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

参考资料:https://beansandanicechianti.blogspot.com/2019/11/mysql-ssl-configuration.html


3
这不仅是正确的答案,而且也是最详细和安全的。如果你在SSL上收到警告,除了沙盒和本地安装之外,你永远不应该跳过它。你向我指出了适用于连接到Azure MySQL的Kubernetes Keycloak 9.0.2集群的正确解决方案。非常感谢! - iakko

30

提及 url,例如:

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

但是在XML配置中,当你提到&符号时,IDE会显示以下错误:

 

实体引用“useSSL”必须以“;”分隔符结束。

然后,您必须显式使用&而不是&来被xml确定为&。在xml中,您必须像这样为xml配置提供url:

<property name="connection.url">jdbc:mysql://hostname:3306/hibernatedb?autoReconnect=true&amp;useSSL=false</property>

@caot,感谢您关于&符号以及如何在连接字符串中编写它的评论。 - qualebs

23

另一种方法是:

    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) {
    ...
    }

听起来不错,但是我该如何将这个内容添加到我的grails-app的application.yml文件中呢? - Fusca Software

12

我也遇到了这个警告,然后通过将连接字符串的SSL=false后缀来修复它,就像这个示例代码一样。

示例:

connectionString = "jdbc:mysql://{server-name}:3306/%s?useUnicode=yes&characterEncoding=UTF-8&useSSL=false"

12

使用此方法解决Hive连接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>

但是为什么它不适用于 and 运算符呢?我有类似 jdbc:mysql://localhost/metastore?useSSL=false&createDatabaseIfNotExist=true 的东西。没有 and 时它可以正常工作。 - Kulasangar
1
对我来说,发布的值运行顺畅,因此我将在2017年12月底将其标记为答案,并使用hive-2.1.1 hive-site.xml进行工作。 - ArifMustafa
1
我在我的hive-site.xml中添加/替换了这个属性,然后它就可以工作了。 - Amit Kumar

10

你需要像这样使用你的MySQL路径:

<property name="url" value="jdbc:mysql://localhost:3306/world?useSSL=true"/>

9
为了在Java中连接数据库时禁用警告,请使用以下概念 -
autoReconnect=true&useSSL=false

只需要像这样更改connectionURL:

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

这将禁用SSL并抑制SSL错误。


在服务器配置文件中有没有一种方法可以做到这一点? - H Aßdøµ

9

对我来说这是可以的:

this.conn = (Connection)DriverManager
    .getConnection(url + dbName + "?useSSL=false", userName, password);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接