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

Tomcat9搭配Temurin JDK11连接SendGrid时出现SSLHandshakeException问题

解决Tomcat9使用Java11运行Grails2应用时SendGrid SSL握手失败问题

问题背景

同一测试服务器的Tomcat9部署了两个应用:基于Oracle JDK1.8.0.221构建的Grails2旧应用,以及基于Temurin JDK11.0.13构建的Grails5新应用。为适配Grails5,通过tomcat/bin/setenv.sh将Tomcat的JAVA_HOME设为Java11后,Grails2应用通过SendGrid发送邮件时抛出错误:

SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suite is inappropriate)

尝试调整应用内的TLS版本与密码套件系统属性(如https.protocols、jdk.tls.client.protocols)均无效,需在同一Tomcat实例中同时兼容两个应用,避免运行多版本Java的Tomcat。

核心原因分析

  1. Java版本安全配置差异:Java11的默认安全策略比Oracle Java8更严格,jdk.tls.disabledAlgorithms默认禁用了部分旧密码套件(如部分DHE系列套件),而Grails2应用依赖的套件可能在Java11中已被禁用。
  2. 系统属性生效逻辑变化:Java11中jdk.tls.client.protocols的优先级与生效方式和Java8不同,应用内直接设置的系统属性可能被全局安全配置覆盖。
  3. Oracle JDK与OpenJDK差异:Oracle JDK8默认包含部分商业加密套件,而Temurin Java11默认未启用这些套件,导致握手时无合适套件匹配。

可行解决方案

方案1:调整Java11的全局安全配置

修改Java11安装目录下的conf/security/java.security文件:

  • 找到jdk.tls.disabledAlgorithms配置项,移除其中影响TLSv1.2的条目,确保TLSv1.2未被禁用,同时删除对DHE_RSA相关套件的禁用规则(测试环境验证后再考虑生产环境的安全风险)。
  • 添加或修改jdk.tls.client.cipherSuites配置,包含SendGrid支持的TLSv1.2兼容套件,示例:
    jdk.tls.client.cipherSuites=TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    

方案2:在Grails2应用内直接配置SSLContext

替换原有的系统属性设置代码,通过代码显式初始化TLSv1.2的SSLContext,绕过全局配置限制:

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

// 初始化TLSv1.2 SSLContext
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) {}
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) {}
    @Override
    public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}
}}, null);

// 设置默认SSL套接字工厂
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
// 设置主机名验证(适配SendGrid域名)
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> hostname.endsWith("sendgrid.net"));

该方式直接控制SSL握手的协议与验证逻辑,不受全局系统属性影响。

方案3:升级Grails2应用的邮件依赖

检查Grails2应用使用的邮件发送库(如JavaMail)版本,升级至兼容Java11的版本(如JavaMail 1.6.2及以上)。旧版本JavaMail在Java11环境中可能存在SSL握手的兼容性问题,升级后可自动适配新的安全规则。

验证步骤

  1. 应用修改或配置调整完成后,重启Tomcat9。
  2. 触发Grails2应用的邮件发送流程,验证是否仍抛出SSL握手异常。
  3. 可通过openssl s_client -connect smtp.sendgrid.net:465 -tls1_2命令查看SendGrid支持的密码套件,确保Java11配置中包含对应套件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:35:48