如何在 Spring Boot 嵌入式 tomcat 中设置 HTTPS SSL 密码套件首选项
Posted
技术标签:
【中文标题】如何在 Spring Boot 嵌入式 tomcat 中设置 HTTPS SSL 密码套件首选项【英文标题】:How to set HTTPS SSL Cipher Suite Preference in Spring boot embedded tomcat 【发布时间】:2017-10-11 22:38:29 【问题描述】:我尝试根据服务器首选项设置 HTTPS SSL 密码套件首选项,而不是根据客户端和服务器支持的最高强度通用密码套件自动选择。
我喜欢让服务器选择具有“TLS_ECDHE...”的服务器和客户端之间的共同点,以支持前向保密。 现在我在“www.ssllabs.com”中进行了测试,客户端浏览器会更喜欢具有“TLS_RSA...”而不是“TLS_ECDHE”的密码...
我注意到 java 8 支持设置密码套件首选项: http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#cipher_suite_preference
我假设 spring boot 嵌入式 Tomcat 将调用 Java 8 函数来选择密码
这是我在 spring boot application.properties 文件中设置服务器支持密码集所做的:
server.ssl.ciphers=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_SHA256,TLS_ECDHE_RSA_WITH_AES_128_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_SHA,TLS_ECDHE_RSA_WITH_AES_256_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_SHA384,TLS_ECDHE_RSA_WITH_AES_256_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_SHA,TLS_DHE_RSA_WITH_AES_128_SHA256,TLS_DHE_RSA_WITH_AES_128_SHA,TLS_DHE_DSS_WITH_AES_128_SHA256,TLS_DHE_RSA_WITH_AES_256_SHA256,TLS_DHE_DSS_WITH_AES_256_SHA,TLS_DHE_RSA_WITH_AES_256_SHA
希望有人可以指导我如何覆盖默认选择密码行为。
【问题讨论】:
【参考方案1】:这是我在 Spring Boot 2.3.4.RELEASE 和 JDK 1.8 中的解决方案。 对我来说效果很好。
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpsConfiguration
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainerCustomizer()
return new WebServerFactoryCustomizer<TomcatServletWebServerFactory>()
@Override
public void customize(TomcatServletWebServerFactory factory)
factory.addConnectorCustomizers(new TomcatConnectorCustomizer()
@Override
public void customize(Connector connector)
AbstractHttp11Protocol<?> httpHandler = ((AbstractHttp11Protocol<?>) connector.getProtocolHandler());
httpHandler.setUseServerCipherSuitesOrder(true);
httpHandler.setSSLProtocol("TLSv1.2");
httpHandler.setSSLHonorCipherOrder(true);
httpHandler.setCiphers("TLS_EMPTY_RENEGOTIATION_INFO_SCSV,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384");
);
;
【讨论】:
【参考方案2】:您需要告诉连接器的底层协议处理程序使用服务器的密码套件顺序。您可以使用WebServerFactoryCustomizer
:
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainerCustomizer()
return (factory) ->
factory.addConnectorCustomizers((c) ->
((AbstractHttp11Protocol<?>) c.getProtocolHandler()).setUseServerCipherSuitesOrder(true));
;
【讨论】:
要将此解决方案升级到 Spring Boot 2.1.x,我只需要进行两个小改动:将EmbeddedServletContainerCustomizer
替换为 WebServerFactoryCustomizer<TomcatServletWebServerFactory>
,将 TomcatEmbeddedServletContainerFactory
替换为 TomcatServletWebServerFactory
。
另外,在 Spring Boot 2.0.7 和 2.1.3 之间的某个地方,setUseServerCipherSuitesOrder
的参数从 String 更改为 boolean。
setUseServerCipherSuitesOrder 现在收到一个布尔值以上是关于如何在 Spring Boot 嵌入式 tomcat 中设置 HTTPS SSL 密码套件首选项的主要内容,如果未能解决你的问题,请参考以下文章
如何在嵌入式 tomcat 服务器上部署 Spring Boot Web 应用程序,来自 Spring Boot 本身
如何在 spring-boot 中拦截嵌入式 Tomcat 上的“全局”404
如何在嵌入式 Spring Boot Keycloak 中设置主题?
如何在 Spring Boot 集成测试中使用嵌入式 MongoDB