如何配置Tomcat使用Oracle JDK 1.7实现出站HTTPS连接TLS1.2
1. 如何让Oracle JDK 1.7环境下的客户端连接使用TLSv1.2?
Oracle JDK 1.7本身支持TLSv1.2,但默认情况下客户端不会优先选用这个协议(早期更新版本甚至默认未启用),你可以通过两种方式强制客户端使用TLSv1.2:
方式一:通过JVM启动参数全局配置
在启动Tomcat时,添加以下JVM系统属性,让所有基于JDK的HTTPS客户端(比如HttpsURLConnection、Apache HttpClient等)默认使用TLSv1.2:
-Dhttps.protocols=TLSv1.2
如果你的Tomcat是通过catalina.sh(Linux)或catalina.bat(Windows)启动的,可以在文件的JAVA_OPTS变量中追加这个参数,比如Linux环境下:
JAVA_OPTS="$JAVA_OPTS -Dhttps.protocols=TLSv1.2"
方式二:在代码层面指定协议(针对特定客户端)
如果只需要让某个API调用的客户端使用TLSv1.2,或者使用了自定义HTTP客户端库,可以在代码中显式创建TLSv1.2的SSLContext并绑定到客户端:
针对Apache HttpClient(4.x版本):
import org.apache.http.client.HttpClient; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.impl.client.HttpClients; SSLContext sslContext = SSLContexts.custom() .useProtocol("TLSv1.2") .build(); HttpClient httpClient = HttpClients.custom() .setSSLContext(sslContext) .build(); // 使用该httpClient执行第三方API调用
针对HttpsURLConnection:
import javax.net.ssl.SSLContext; import javax.net.ssl.HttpsURLConnection; URL url = new URL("https://third-party-api-domain.com"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); // 创建TLSv1.2的SSL上下文 SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, null, new java.security.SecureRandom()); conn.setSSLSocketFactory(sslContext.getSocketFactory()); // 后续执行连接、请求逻辑
额外注意事项
- 确保你的Oracle JDK 1.7是较新的更新版本(比如1.7u131及以上),早期1.7版本对TLSv1.2的支持存在兼容性问题,可能导致连接失败;
- 如果使用了第三方安全库(比如BouncyCastle),需确保库版本兼容TLSv1.2。
2. 开启TLSv1.2后,服务器是否会自动对入站连接采用TLSv1.2?对浏览器客户端有哪些影响?
服务器不会自动启用TLSv1.2入站连接
你针对客户端设置的TLSv1.2配置(比如JVM参数-Dhttps.protocols)只会影响你的应用作为客户端调用外部服务的行为,不会自动修改Tomcat作为服务器接收入站HTTPS连接的协议配置。
要让Tomcat的入站HTTPS连接支持TLSv1.2,需要手动修改server.xml中的<Connector>配置:
针对Tomcat 8.5+版本(推荐):
在SSLHostConfig标签中指定protocols属性:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="conf/your-keystore.jks" type="RSA" protocols="TLSv1.2"/> <!-- 指定仅使用TLSv1.2 --> </SSLHostConfig> </Connector>
针对Tomcat 7.x版本:
使用sslEnabledProtocols属性指定支持的协议:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2"/> <!-- 指定仅使用TLSv1.2 -->
对浏览器客户端的影响
如果Tomcat仅启用TLSv1.2作为入站协议,那么不支持TLSv1.2的旧浏览器将无法访问你的应用,这类浏览器包括:
- Windows 7及以下系统中的IE 8~10(默认未启用TLSv1.2,需手动在浏览器设置中开启);
- IE 11(Windows 7)可能需要手动开启TLSv1.2;
- Chrome 49及以下、Firefox 44及以下等非常旧的浏览器版本。
如果你的用户群体包含大量使用这些旧浏览器的用户,建议配置Tomcat支持多个兼容协议,兼顾安全性与兼容性:
<!-- Tomcat 8.5+示例 --> <SSLHostConfig protocols="TLSv1,TLSv1.1,TLSv1.2">
内容的提问来源于stack exchange,提问作者Anupama

