使用AWS Secrets Manager存储RDS密码时的SSL握手问题排查
问题分析与修复原理
场景回顾
生产环境架构:
- 持久化存储:AWS RDS
- 密码管理:AWS Secrets Manager(KMS加密存储,自动轮转)
- 应用部署:Spring Boot 部署在 ECS Fargate
- 核心依赖:
com.amazonaws.secretsmanager:aws-secretsmanager-jdbc:1.0.5 - 自定义JRE:通过
jdeps+jlink构建,包含模块:Java.base,java.desktop,java.instrument,java.management.rmi,java.naming,java.prefs, java.scripting,java.security.jgss,java.sql,jdk.httpserver,jdk.jfr,jdk.unsupported
该配置稳定运行数月后,本月突发SSL握手失败,未更新过应用依赖或框架版本,添加jdk.crypto.ec模块或配置启动参数-Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2可解决问题。
突发问题的根本原因
问题并非源于应用自身的版本变更,而是AWS服务端的TLS安全配置发生了变更,与自定义JRE的兼容性缺口触发了握手失败:
- AWS近期可能升级了RDS或Secrets Manager端点的TLS协议策略:比如默认启用TLS 1.3,或调整了允许的加密套件列表,强制要求使用椭圆曲线(EC)类加密算法(如ECDHE密钥交换、ECDSA证书签名);
- 你构建的自定义JRE未包含
jdk.crypto.ec模块,JVM无法支持EC类加密算法,导致与AWS服务端协商加密套件时无法达成一致,最终触发SSL握手错误。
修复方案生效原理
1. 添加jdk.crypto.ec模块
jdk.crypto.ec是JDK官方提供的模块,专门实现椭圆曲线加密相关的算法、密钥管理及加密套件支持。添加该模块后:
- JVM能够识别并支持AWS服务端要求的EC类加密套件;
- 在TLS握手阶段,可与服务端成功协商符合安全要求的加密套件,完成SSL连接建立。
2. 配置启动参数-Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2
这个参数强制JVM在TLS握手时仅使用指定的旧版本协议:
- TLS 1.3对EC加密的依赖度极高,而TLSv1.0/1.1/1.2的加密套件池包含大量非EC类选项(如RSA密钥交换);
- 强制使用旧协议后,JVM会与AWS服务端协商兼容的非EC加密套件,绕过了对
jdk.crypto.ec模块的依赖,从而成功完成握手。
注意:TLSv1.0和TLSv1.1已被列为不安全协议,存在安全风险,建议优先采用添加
jdk.crypto.ec模块的方案,以保障通信安全性。
内容的提问来源于stack exchange,提问作者Akash tiwari
相关产品推荐
相关产品推荐

