How to set HTTPS SSL Cipher Suite Preference in Spring boot embedded tomcat

11,419

Solution 1

You need to tell the connector's underlying protocol handler to use the server's cipher suite order. You can do so with a WebServerFactoryCustomizer :

@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainerCustomizer() {
    return (factory) -> {
        factory.addConnectorCustomizers((c) -> 
            ((AbstractHttp11Protocol<?>) c.getProtocolHandler()).setUseServerCipherSuitesOrder(true));
    };
}

Solution 2

Here is my solution in Spring Boot 2.3.4.RELEASE and JDK 1.8.
It works fine for me.

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");
                    }
                });
            }
        };
    }

}
Share:
11,419

Related videos on Youtube

Mr Hoelee
Author by

Mr Hoelee

I'm very welcome for any short-term web development projects, preferable remote working style. For the company who like to build an online existence, I would like to help out. I'm partnering with few people, offering complete business solutions, starting from planning, design, develop until marketing. Services Offer: Website Development &amp; Design Website Troubleshoot &amp; Consultant Website &amp; Email Hosting Facebook Management &amp; Marketing Google SEO &amp; SEM Professional Graphic Design For those who are interested, may drop me an email - [email protected] Thanks.

Updated on June 04, 2022

Comments

  • Mr Hoelee
    Mr Hoelee almost 2 years

    I trying to set HTTPS SSL cipher suite preference according to server preference rather than auto select based on client & server supported common cipher suite with highest strength.

    I like to let server choose for common between server & client having "TLS_ECDHE..." in order to support Forward Secrecy. Now I tested in "www.ssllabs.com", client browser will prefer cipher having "TLS_RSA..." rather than "TLS_ECDHE"...

    I noticed java 8 support set cipher suite preference: http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#cipher_suite_preference

    I assume spring boot embedded Tomcat will call Java 8 function to choose cipher

    Here is what I done in spring boot application.properties file to set server support ciphers set:

    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
    

    Hopefully someone can guide me how to override default choose cipher behaviour.

  • Bampfer
    Bampfer about 5 years
    To upgrade this solution to Spring Boot 2.1.x, I just had to make two small changes: replace EmbeddedServletContainerCustomizer with WebServerFactoryCustomizer<TomcatServletWebServerFactory>, and TomcatEmbeddedServletContainerFactory with TomcatServletWebServerFactory.
  • Bampfer
    Bampfer about 5 years
    Plus, somewhere between Spring Boot 2.0.7 and 2.1.3 the argument to setUseServerCipherSuitesOrder changed from String to boolean.
  • Julian Solarte
    Julian Solarte over 4 years
    setUseServerCipherSuitesOrder now recieves a boolean