我正在尝试制作一个使用jdbc(连接器/ J)使用SSL加密连接到mariadb数据库的Java应用程序。 我已经创建了一个自签名证书,并配置了服务器以使用它。 当我尝试连接时,由于证书不受信任,因为证书是自签名的,并且未添加到Java信任库中,因此出现异常。 因为我想修改TrustStore或为我的应用程序使用其他证书,所以我寻求一种仅告诉jdbc受信任的证书的方法,并发现“ https://mariadb.com/kb/en/library/using-tlsssl-with-mariadb-connectorj/直接提供证书”
当我现在尝试连接时:
DriverManager.getConnection("jdbc:mysql://<hostname>:3306/<database>?useSSL=true&requireSSL=true&serverSslCert=/tmp/ssl/server-cert.pem", "<username>", "<password>");
在再次不使用serverSslCert参数之前,我已经获得了此异常:
Exception in thread "main"
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 136 milliseconds ago. The last packet sent successfully to the server was 129 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:203)
at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4901)
at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1659)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1226)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2188)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2219)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2014)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:776)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:386)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330)
at gymcash.server.mysql.DriverWrapper.connect(DriverWrapper.java:22)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at gymcash.server.mysql.MySQL.connect(MySQL.java:48)
at gymcash.server.mysql.MySQL.connect(MySQL.java:52)
at gymcash.server.main.Main.main(Main.java:25)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1964)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:188)
... 21 more
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at com.mysql.jdbc.ExportControlled$X509TrustManagerWrapper.checkServerTrusted(ExportControlled.java:304)
at
sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:992)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
... 29 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:154)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:80)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
at com.mysql.jdbc.ExportControlled$X509TrustManagerWrapper.checkServerTrusted(ExportControlled.java:297)
... 31 more
我不明白我在做什么错,因为文件存在,路径是绝对的,并且与服务器使用的路径相同。有人可以告诉我我在做什么错吗?
我正在使用Java 8,mysql-connector-java-5.1.45
答案 0 :(得分:1)
有几种方法可以做到这一点。可以将您自己签名的证书或用于对证书进行签名的证书颁发机构放到用于连接的JVM使用的默认Java密钥存储中。您需要使用Keytool来做到这一点。但是,除非您管理企业VM软件包,否则您可能不想劫持该安全软件包中的默认密钥库。
首先,您需要了解关键工具的工作方式。
[Java密钥工具命令] [1] https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html
问题是您可能无权访问默认密钥存储,并且可能不接受您使用的证书格式。需要一些健身房工作来转换证书,并尝试匹配支持的加密算法。
通常,除非您管理一家企业,否则
我通常只需将其添加到我的代码中并设置属性,然后再连接到数据库
if (DB_SSL || SSL) {
System.setProperty("javax.net.ssl.keyStore", KEYSTORE);
System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASS);
System.setProperty("javax.net.ssl.trustStore", KEYSTORE);
System.setProperty("javax.net.ssl.trustStorePassword", KEYSTORE_PASS);
if (DEBUG_OPTION) {
System.setProperty("javax.net.debug", "true");
}
}
private static String KEYSTORE = "/home/me/.keystore";
private static String KEYSTORE_PASS = "changeit";