You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级AWS Aurora证书rds-ca-ecc384-g1后SpringBoot无法连PostgreSQL

AWS Aurora证书更新后SpringBoot应用无法连接PostgreSQL

我有一个部署在AWS BeanStalk上的SpringBoot应用,此前通过以下配置可以正常连接PostgreSQL,但在将AWS Aurora证书更新为rds-ca-ecc384-g1后,应用无法建立连接,出现SSL握手失败错误。

原数据库连接配置

spring.datasource.url=jdbc:postgresql://{SUBDOMAIN}.us-east-2.rds.amazonaws.com:5432/{DATABASE_NAME}
spring.datasource.username={USER}
spring.datasource.password={PASSWORD}
spring.datasource.hikari.maximum-pool-size=2
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.open-in-view=false
spring.jpa.hibernate.ddl-auto=create

应用报错信息

org.postgresql.util.PSQLException: SSL error: Received fatal alert: handshake_failure
    at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:43) ~[postgresql-42.5.4.jar!/:42.5.4]
    at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:620) ~[postgresql-42.5.4.jar!/:42.5.4]
    at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:191) ~[postgresql-42.5.4.jar!/:42.5.4]
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:258) ~[postgresql-42.5.4.jar!/:42.5.4]
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54) ~[postgresql-42.5.4.jar!/:42.5.4]
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:253) ~[postgresql-42.5.4.jar!/:42.5.4]
    at org.postgresql.Driver.makeConnection(Driver.java:434) ~[postgresql-42.5.4.jar!/:42.5.4]
    at org.postgresql.Driver.connect(Driver.java:291) ~[postgresql-42.5.4.jar!/:42.5.4]
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-5.0.1.jar!/:na]
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) ~[HikariCP-5.0.1.jar!/:na]
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) ~[HikariCP-5.0.1.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) ~[HikariCP-5.0.1.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[HikariCP-5.0.1.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100) ~[HikariCP-5.0.1.jar!/:na]
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-5.0.1.jar!/:na]
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:284) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:177) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:36) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:255) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:230) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.boot.model.relational.Database.<init>(Database.java:44) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:218) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:191) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:138) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1348) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1419) ~[hibernate-core-6.1.7.Final.jar!/:6.1.7.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.0.11.jar!/:6.0.11]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.0.11.jar!/:6.0.11]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.0.11.jar!/:6.0.11]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.0.11.jar!/:6.0.11]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[spring-orm-6.0.11.jar!/:6.0.11]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1817) ~[spring-beans-6.0.11.jar!/:6.0.11]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766) ~[spring-beans-6.0.11.jar!/:6.0.11]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.11.jar!/:6.0.11]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.11.jar!/:6.0.11]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.11.jar!/:6.0.11]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.11.jar!/:6.0.11]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.11.jar!/:6.0.11]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.11.jar!/:6.0.11]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1155) ~[spring-context-6.0.11.jar!/:6.0.11]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-6.0.11.jar!/:6.0.11]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[spring-context-6.0.11.jar!/:6.0.11]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.10.jar!/:3.0.10]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-3.0.10.jar!/:3.0.10]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-3.0.10.jar!/:3.0.10]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-3.0.10.jar!/:3.0.10]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[spring-boot-3.0.10.jar!/:3.0.10]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[spring-boot-3.0.10.jar!/:3.0.10]
    at com.app.Main.main(Main.java:18) ~[classes!/:1.0-SNAPSHOT]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[main-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:95) ~[main-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[main-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) ~[main-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) ~[na:na]
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:365) ~[na:na]
    at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:204) ~[na:na]
    at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1510) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1425) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426) ~[na:na]
    at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:41) ~[postgresql-42.5.4.jar!/:42.5.4]
    ... 59 common frames omitted

手动psql连接报错

$ PGSSLMODE=verify-full psql -h {SUBDOMAIN}.us-east-2.rds.amazonaws.com -p 5432 -U {USER} -W {DATABASE_NAME}
Password:
psql: error: connection to server at "{SUBDOMAIN}.us-east-2.rds.amazonaws.com" (10.0.156.184), port 5432 failed: root certificate file "/home/ec2-user/.postgresql/root.crt" does not exist
Either provide the file or change sslmode to disable server certificate verification.

解决方法

给SpringBoot应用配置新CA证书

更新Aurora证书后,应用的JVM默认信任存储里没有rds-ca-ecc384-g1的根证书,导致SSL握手失败。可以通过两种方式修复:

  1. 在JDBC URL中直接指定证书
    把rds-ca-ecc384-g1.pem证书文件放到应用的src/main/resources目录下,然后修改JDBC URL:

    spring.datasource.url=jdbc:postgresql://{SUBDOMAIN}.us-east-2.rds.amazonaws.com:5432/{DATABASE_NAME}?sslmode=verify-full&sslrootcert=classpath:rds-ca-ecc384-g1.pem
    
  2. 导入证书到JVM信任存储
    如果不想修改URL,可以把证书导入到应用使用的JVM信任存储:

    # 下载证书
    curl -o rds-ca-ecc384-g1.pem https://truststore.pki.rds.amazonaws.com/us-east-2/rds-ca-ecc384-g1.pem
    # 导入到JVM信任存储(路径根据你的JDK安装位置调整)
    keytool -importcert -file rds-ca-ecc384-g1.pem -alias rds-ecc-ca -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
    

    注意:如果是AWS BeanStalk环境,可能需要通过自定义配置脚本完成证书导入,或者使用应用的自定义信任存储并在启动参数中指定。

修复psql命令行连接

psql报错是因为找不到指定路径的根证书,只需把证书放到要求的位置:

mkdir -p ~/.postgresql/
curl -o ~/.postgresql/root.crt https://truststore.pki.rds.amazonaws.com/us-east-2/rds-ca-ecc384-g1.pem
chmod 600 ~/.postgresql/root.crt

执行以上命令后再重新连接即可。

额外检查点

  • 确认PostgreSQL JDBC驱动版本:你的版本42.5.4已经支持ECC证书,若仍有问题可以尝试升级到最新稳定版。
  • 检查JDK版本:JDK 8u161及以上默认支持ECC算法,确保BeanStalk使用的JDK版本符合要求。

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:36:09