MySQL使用ssl连接,java通过ssl连接数据库

MySQL使用ssl连接,java通过ssl连接数据库

用了一天的时间去解决这个问题,事情要从一个异常开始说起。当我把项目war包部署到阿里云服务器上,启动后一开始出现了PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target这个异常,搜了一下,发现大部分解决方案都是配置https出现的证书问题,我就感觉这个方向不太对,因为这个项目是http,于是看了看日志,往上翻发现了连接不到数据库的异常,在url: jdbc:mysql://127.0.0.1:3306/website?useUnicode=true&serverTimezone=GMT&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&allowMultiQueries=true&useSSL=true&requireSSL=true中有有两个参数useSSLrequireSSL引起了我的注意,参数意思如下:

参数说明
useSSL是否建立SSL连接
requireSSLmysql服务器不支持SSL连接就会失败
于是顺着ssl这个方向找到了解决方案。

2021-07-07 16:38:32.063 ERROR 28343 --- [eate-1114877028] c.a.d.p.DruidDataSource                  : create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/website?useUnicode=true&serverTimezone=GMT&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&allowMultiQueries=true&useSSL=true&requireSSL=true, errorCode 0, state 08001

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_101]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_101]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_101]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_101]
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.Util.getInstance(Util.java:387) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:917) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2163) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2088) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:806) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_101]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_101]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_101]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_101]
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:410) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:328) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:149) ~[druid-1.1.9.jar:1.1.9]
	at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:218) ~[druid-1.1.9.jar:1.1.9]
	at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:143) ~[druid-1.1.9.jar:1.1.9]
	at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1515) ~[druid-1.1.9.jar:1.1.9]
	at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1578) ~[druid-1.1.9.jar:1.1.9]
	at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2466) [druid-1.1.9.jar:1.1.9]
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 4 milliseconds ago.  The last packet sent successfully to the server was 4 milliseconds ago.
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_101]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_101]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_101]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_101]
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:988) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:164) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4894) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1661) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1228) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2253) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2104) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	... 16 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) ~[?:1.8.0_101]
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) ~[?:1.8.0_101]
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) ~[?:1.8.0_101]
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) ~[?:1.8.0_101]
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) ~[?:1.8.0_101]
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) ~[?:1.8.0_101]
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) ~[?:1.8.0_101]
	at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:149) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4894) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1661) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1228) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2253) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2104) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	... 16 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) ~[?:1.8.0_101]
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[?:1.8.0_101]
	at sun.security.validator.Validator.validate(Validator.java:260) ~[?:1.8.0_101]
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) ~[?:1.8.0_101]
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) ~[?:1.8.0_101]
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) ~[?:1.8.0_101]
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) ~[?:1.8.0_101]
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) ~[?:1.8.0_101]
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) ~[?:1.8.0_101]
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) ~[?:1.8.0_101]
	at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:149) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4894) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1661) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1228) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2253) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2104) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[?:1.8.0_101]
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[?:1.8.0_101]
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[?:1.8.0_101]
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ~[?:1.8.0_101]
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[?:1.8.0_101]
	at sun.security.validator.Validator.validate(Validator.java:260) ~[?:1.8.0_101]
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) ~[?:1.8.0_101]
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) ~[?:1.8.0_101]
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) ~[?:1.8.0_101]
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) ~[?:1.8.0_101]
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) ~[?:1.8.0_101]
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) ~[?:1.8.0_101]
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) ~[?:1.8.0_101]
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) ~[?:1.8.0_101]
	at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:149) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4894) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1661) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1228) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2253) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2104) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	... 16 more

MySQL驱动与MySQL版本的关系

链接: https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-versions.html.

  1. 有两个版本的 MySQL Connector/J 可用:
    Connector/J 5.1 提供与 MySQL 的所有功能的兼容性,包括 5.6、5.7 和 8.0。
    Connector/J 8.0 提供与 MySQL 5.6、5.7 和 8.0 的所有功能的兼容性。
    强烈建议将 MySQL Connector/J 8.0 与 MySQL Server 8.0、5.7 和 5.6 一起使用。请升级到 MySQL Connector/J 8.0。
  2. 下表总结了可用的 Connector/J 版本,以及不同版本的 JDBC、MySQL Server 和 Java 的兼容性信息,以及每个 Connector/J 版本的支持状态:
    Connector/J 版本汇总
    版本比对汇总
  3. maven库链接: https://mvnrepository.com/.

什么是SSL?

SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。SSL/TLS协议提供的服务主要有:
1.认证用户和服务器,确保数据发送到正确的客户机和服务器;
2.加密数据以防止数据中途被窃取;
3.维护数据的完整性,确保数据在传输过程中不被改变。

MySQL5.7.34 ssl配置文件和参数

安装后在/var/lib/mysql目录下多了以.pem结尾的文件
pem文件

文件名说明
ca-key.pemCA私钥
ca.pem自签的CA证书,客户端连接也需要提供
client-cert.pem客户端连接服务器端需要提供的证书文件
client-key.pem客户端连接服务器端需要提供的私钥文件
private_key.pem私钥/公钥对的私有成员
public_key.pem私钥/公钥对的共有成员
server-cert.pem服务器端证书文件
server-key.pem服务器端私钥文件
  • 1.连接MySQL
    命令行参数

  • 2.查看ssl开启情况:YES表示已开启ssl
    ssl开启情况

  • 3.查看用户的连接方式\s:Not in use 表示该用户不是采用SSL连接到MySQL服务器上的。
    连接方式

MySQL服务器端配置ssl

  • 1.修改mysqld配置文件
    mysqld.cnf文件位置

  • 2.编辑mysqld.cnf配置文件,取消文件末尾最后三行的注释,并修改ca证书、server-cert.pem,server-key.pem文件的所在路径。
    文件内容

  • 3.接着找到bind-address这一行,前面添加#注释。使可以接收所有客户端。
    在这里插入图片描述
    可通过netstat -an |grep 3306来查看MySQL3306端口状态
    在这里插入图片描述

  • 4.重启MySQL服务。

systemctl restart mysql.service
  • 5.使用MySQL命令行,执行创建远程用户强制使用ssl登录的命令,并刷新权限。
    root用户使用ssl登录
  • 6.配置好root用户后,使用root用户重新登录MySQL。其中参数–ssl-cert和–ssl-key的值要写pem文件所在的路径。
mysql -uroot -p密码 -h 47.95.111.246 --ssl-cert=/var/lib/mysql/client-cert.pem --ssl-key=/var/lib/mysql/client-key.pem
  • 7.登录成功后,这时再执行\s命令。Cipher in use is XXX表示该用户采用ssl登录
    在这里插入图片描述

  • 8.执行 show variables like ‘%ssl%’ 语句。可以看到这时的参数ssl_ca,ssl_cer,ssl_key指向的就是pem文件所在的真实路径。
    在这里插入图片描述

配置java环境通过ssl连接数据

  • 1.使用命令生成java使用ssl连接所需要的文件。
    -file 后面的参数要写pem文件的路径
keytool -importcert  -file ca-cert.pem -keystore truststore -storepass 密码

在这里插入图片描述
truststore 位置和密码一定要记住!!! 后面有用到

  • 2.设置java系统变量
    执行命令行vim /etc/profile
    添加如下代码
    在这里插入图片描述
    执行source /etc/profile 命令使其生效

修改yml文件中jdbc连接url

url: jdbc:mysql://127.0.0.1:3306/website?useUnicode=true&serverTimezone=GMT&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&allowMultiQueries=true&useSSL=true&requireSSL=true&trustCertificateKeyStoreUrl=file:/var/lib/mysql/truststore&trustCertificateKeyStorePassword=密码

连接参数说明
useSSL是否建立SSL连接
verifyServerCertificate是否需要检验mysql服务器的证书
requireSSL如果mysql服务器不支持SSL连接就会失败
clientCertificateKeyStoreUrlkeystore文件
clientCertificateKeyStorePasswordkeystore密码
trustCertificateKeyStoreUrltruststore文件
trustCertificateKeyStorePasswordtruststore密码
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好,要在Java连接MySQL数据库,您需要执行以下步骤: 1. 下载并安装JDBC驱动程序 2. 导入MySQL JDBC驱动 3. 创建一个连接字符串,指定MySQL服务器的位置和要连接数据库名称 4. 建立一个数据库连接 5. 使用JDBC API执行SQL查询和更新 以下是一个示例代码: ```java import java.sql.*; public class MySQLConnection { public static void main(String[] args) { Connection conn = null; try { String url = "jdbc:mysql://localhost:3306/mydatabase?serverTimezone=UTC&useSSL=false"; String user = "root"; String password = "yourpassword"; Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url, user, password); System.out.println("Successfully connected to the database."); } catch (SQLException ex) { System.out.println("An error occurred while connecting to the database: " + ex.getMessage()); } catch (ClassNotFoundException ex) { System.out.println("The specified JDBC driver was not found: " + ex.getMessage()); } finally { if (conn != null) { try { conn.close(); } catch (SQLException ex) { System.out.println("An error occurred while closing the connection: " + ex.getMessage()); } } } } } ``` 在上面的示例中,“url”参数指定了要连接MySQL服务器的位置和要连接数据库名称。 “user”和“password”参数指定要使用数据库用户的凭据。 “Class.forName()”语句将MySQL JDBC驱动程序导入Java程序中。最后,在“finally”块中,我们关闭数据库连接以防止资源泄漏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值