gpt4 book ai didi

java - 使用 SSL(自签名)证书通过 Spring 和 Hibernate 连接 MariaDB

转载 作者:行者123 更新时间:2023-11-30 09:06:34 25 4
gpt4 key购买 nike

我用 Spring 和 Hibernate 开发了 J2EE 应用程序。现在我想使用 SSL 证书将我的应用程序与 MariaDB 连接(不使用密码)我可以使用以下命令连接到我的数据库

mysql -h myhost.com -P3306 -umyuser --ssl-ca ca.crt --ssl-cert app.crt --ssl-key my-key.pem

但是我无法将我的应用程序连接到数据库,因为出现以下错误

错误日志

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)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2270)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:723)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:146)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:195)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:184)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:200)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1086)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1073)
at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:44)
at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1810)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:648)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Last packet sent to the server was 71 ms ago.
at sun.reflect.GeneratedConstructorAccessor37.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:104)
at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4502)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1322)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2198)
... 18 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)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:89)
... 21 more

读完这篇 question 我已使用以下命令将证书添加到 keystore 中:

keytool -import -noprompt -trustcacerts -alias "My App Certificate" -file ca.crt -keystore /usr/lib/jvm/java-1.6.0-openjdk/jre/lib/security/cacerts -storepass mypassword

在我的配置文件之后仍然出现以下错误

JDBC.properties

jdbc.initialPoolSize=10
jdbc.maxPoolSize=30
jdbc.minPoolSize=5
jdbc.acquireIncrement=3
jdbc.acquireRetryAttempts=0
jdbc.preferredTestQuery=SELECT 1
jdbc.idleConnectionTestPeriod=600
jdbc.numHelperThreads=10
jdbc.debugUnreturnedConnectionStackTraces=true
jdbc.mydbUrl=jdbc:mysql://myhost.com:3306/mydb?verifyServerCertificate=true&useSSL=true&requireSSL=true&characterEncoding=utf8
jdbc.mydbUsername=myuser

datasource-context.xml

<bean id="mydbCommon" class="com.mchange.v2.c3p0.ComboPooledDataSource" abstract="true" destroy-method="close">
<property name="driverClass" value="${jdbc.rptdbDriverClassName}"/>
<!-- Common properties for all DS -->
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
<property name="minPoolSize" value="${jdbc.minPoolSize}"/>
<property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>
<property name="acquireRetryAttempts" value="${jdbc.acquireRetryAttempts}"/>
<property name="preferredTestQuery" value="${jdbc.preferredTestQuery}"/>
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>
<property name="numHelperThreads" value="${jdbc.numHelperThreads}"/>
<property name="debugUnreturnedConnectionStackTraces" value="${jdbc.debugUnreturnedConnectionStackTraces}"/>
</bean>
<bean id="mydb" parent="mydbCommon">
<property name="jdbcUrl" value="${jdbc.mydbUrl}"/>
<property name="user" value="${jdbc.mydbUsername}"/>
</bean>

谁能帮忙解决这个问题。提前致谢...

最佳答案

以下是我解决问题的步骤,这不是我的创意,只是收集了以下文章中提到的一些步骤。

引用资料

Connecting Securely Using SSL

The Most Common OpenSSL Commands

为了使用 SSL 加密连接到您的数据库,您需要:

  • 您的数据库管理员协助配置 MySQL服务器接受 SSL 连接。
  • 对应于您的服务器的 SSL PEM 公钥文件加密 key 。

检查您的 MySQL 服务器是否支持 SSL 的步骤

使用以下命令检查您的服务器是否支持 SSL

show variables like 'have_ssl'

如果你的服务器的回答是

NO 那么服务器没有编译到它的 SSL 支持。DISABLED,您的系统管理员不会在启用 SSL 的情况下启动 MySQL 服务器。,您可以使用 SSL。

如果你想为 SSL 配置 MySQL,那么你需要遵循 MySql 文档

6.3.6.2 Configuring MySQL for SSL

按照以下步骤配置您的 Java 环境以将服务器的 SSL 证书与 JDBC 一起使用。

系统通过两个 Java truststore 文件工作,

  • 一个文件包含服务器的证书信息(以下示例中的信任库)
  • 另一个文件包含客户端的证书(keystore in下面的例子)

注意:所有 Java 信任库文件都受密码保护,方法是在创建文件时向 key 工具提供合适的密码。您需要文件名和关联的密码才能创建 SSL 连接。

创建信任库文件。

您首先需要将 MySQL 服务器 CA 证书导入 Java 信任库。示例 MySQL 服务器 CA 证书位于 MySQL 源代码分发的 SSL 子目录中。这是 SSL 将用来确定您是否正在与安全的 MySQL 服务器通信的内容。或者,使用您生成的或由您的 SSL 提供商提供的 CA 证书。

注意:假设 keytool 在您的路径中。 keytool 通常位于 JDK 或 JRE 的 bin 子目录中

shell> keytool -import -alias dbServerCACert -file ca.crt -keystore truststore
Enter keystore password: truststorepwd
Re-enter new password: truststorepwd
....
Trust this certificate? [no]: yes
Certificate was added to keystore

创建 keystore 文件。

首先我们必须使用以下命令生成一个空的 Java keystore 文件

shell>keytool -genkey -alias dbkeystore -keystore my-app.jks
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: mycomp
What is the name of your organizational unit?
[Unknown]: mycomp
What is the name of your organization?
[Unknown]: mycomp
What is the name of your City or Locality?
[Unknown]: Singapore
What is the name of your State or Province?
[Unknown]: Singapore
What is the two-letter country code for this unit?
[Unknown]: SG
Is CN=mycomp , OU=mycomp, O=mycomp, L=Singapore, ST=Singapore, C=SG correct?
[no]: yes

Enter key password for <keystore>
(RETURN if same as keystore password):

shell>keytool -delete -alias dbkeystore -keystore my-app.jks
Enter keystore password: keystorepwd

使用以下命令将您的客户端证书 (my-app.crt) 和私钥 (my-app.key) 转换为 pkcs12 文件

shell>openssl pkcs12 -export -name dbkeystore -in my-app.crt -inkey my-app.key -out my-app.p12
Enter Export Password: keystorepwd
Verifying - Enter Export Password: keystorepwd

使用以下命令将您的 p12 文件导入 keystore

keytool -importkeystore -destkeystore my-db.jks -srckeystore my-app.p12 -srcstoretype pkcs12 -alias dbkeystore

设置 JVM 变量

最后,要使用您生成的keystore和truststore,您需要设置JVM的以下系统属性

-Djavax.net.ssl.keyStore=/path/to/my-app.jks
-Djavax.net.ssl.keyStorePassword=keystorepwd
-Djavax.net.ssl.trustStore=/path/to/truststore
-Djavax.net.ssl.trustStorePassword=truststorepwd

更新您的连接 URL 以支持 SSL

您还需要在 MySQL Connector/J 的连接参数中将 useSSL 设置为 true,方法是将 useSSL=true 添加到您的 URL

jdbc:mysql://<HOST>:<PORT>/DB?verifyServerCertificate=true&useSSL=true&requireSSL=true

运行测试应用程序以检查所有文件是否正常

static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://<HOST>:<PORT>/DB?verifyServerCertificate=true&useSSL=true&requireSSL=true"
public static void main(String[] args) {
Connection conn = null;
try {
Class.forName(JDBC_DRIVER);
// STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
}
}
}
}

这个步骤对我有用,希望对你有帮助......!

关于java - 使用 SSL(自签名)证书通过 Spring 和 Hibernate 连接 MariaDB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24402237/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com