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中有有两个参数useSSL,requireSSL引起了我的注意,参数意思如下:
参数 | 说明 |
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.<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.
- 有两个版本的 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。 - 下表总结了可用的 Connector/J 版本,以及不同版本的 JDBC、MySQL Server 和 Java 的兼容性信息,以及每个 Connector/J 版本的支持状态:
Connector/J 版本汇总 - 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结尾的文件
文件名 | 说明 |
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
- 3.查看用户的连接方式\s:Not in use 表示该用户不是采用SSL连接到MySQL服务器上的。
MySQL服务器端配置ssl
- 1.修改mysqld配置文件
- 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登录的命令,并刷新权限。
- 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连接就会失败 |
clientCertificateKeyStoreUrl | keystore文件 |
clientCertificateKeyStorePassword | keystore密码 |
trustCertificateKeyStoreUrl | truststore文件 |
trustCertificateKeyStorePassword | truststore密码 |