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

java 通过ssl连接数据库

  • MySQL使用ssl连接,java通过ssl连接数据库
      • MySQL驱动与MySQL版本的关系
    • 什么是SSL?
    • MySQL5.7.34 ssl配置文件和参数
    • MySQL服务器端配置ssl
    • 配置java环境通过ssl连接数据
    • 修改yml文件中jdbc连接url

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连接
requireSSL mysql服务器不支持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.(ConnectionImpl.java:806) ~[mysql-connector-java-5.1.39.jar:5.1.39]
	at com.mysql.jdbc.JDBC4Connection.(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 版本汇总
    MySQL使用ssl连接,java通过ssl连接数据库_第1张图片
  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结尾的文件
MySQL使用ssl连接,java通过ssl连接数据库_第2张图片

文件名 说明
ca-key.pem CA私钥
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
    MySQL使用ssl连接,java通过ssl连接数据库_第3张图片

  • 3.查看用户的连接方式\s:Not in use 表示该用户不是采用SSL连接到MySQL服务器上的。
    MySQL使用ssl连接,java通过ssl连接数据库_第4张图片

MySQL服务器端配置ssl

  • 1.修改mysqld配置文件
    MySQL使用ssl连接,java通过ssl连接数据库_第5张图片

  • 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登录
    MySQL使用ssl连接,java通过ssl连接数据库_第6张图片

  • 8.执行 show variables like ‘%ssl%’ 语句。可以看到这时的参数ssl_ca,ssl_cer,ssl_key指向的就是pem文件所在的真实路径。
    MySQL使用ssl连接,java通过ssl连接数据库_第7张图片

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

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

MySQL使用ssl连接,java通过ssl连接数据库_第8张图片
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连接就会失败
clientCertificateKeyStoreUrl keystore文件
clientCertificateKeyStorePassword keystore密码
trustCertificateKeyStoreUrl truststore文件
trustCertificateKeyStorePassword truststore密码

你可能感兴趣的:(项目相关,mysql,ssl,java)