spring-boot: WebTestClient protocol/cipher-suite explicitly specified not working

Issue

I’ve been playing with Java 17 and TLSv1.3. I’m getting ciphersuite/protocol unavailable while specifying the correct TLS_CHACHA20_POLY1305_SHA256 for TLSv1.3 and TLS_AES_256_GCM_SHA384 for TLSv1.2 with WebTestClient. Here are the relevant code sections and logs.

application.yml

server:
  port: 8443
  ssl:
    enabled: true
    key-store-type: PKCS12
    key-store: classpath:keystore/localhost.p12
    key-store-password: ${LOCALHOST_KEYSTORE_PASSWORD}
    key-alias: localhost
    ciphers:
      - TLS_CHACHA20_POLY1305_SHA256
      - TLS_AES_256_GCM_SHA384
      - TLS_AES_128_GCM_SHA256
      - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
      - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
      - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
      - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    enabled-protocols:
      - TLSv1.3
      - TLSv1.2

WebTestClient construction

  protected def getHttpClient(String protocol, List<String> cipherSuites) {
    def httpClient = HttpClient
      .create().secure({
        it.sslContext(SslContextBuilder
          .forClient()
          .trustManager(InsecureTrustManagerFactory.INSTANCE)
          .protocols(protocol)
          .ciphers(cipherSuites)
          .build())
      })
    WebTestClient
      .bindToServer(new ReactorClientHttpConnector(httpClient))
      .baseUrl(getBaseUrl())
      .build()
  }

Tests (in Groovy/Spock, sorry)

  def "when TLSv1.2 allowed cipher suite used then accepted"() {
        given:
        def client = getHttpClient(TestConstants.TLSV1_2, List.of("TLS_AES_256_GCM_SHA384"))
        expect:
        client
                .get()
                .uri("/posts/${TestConstants.TEST_UUID}")
                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .exchange()
                .expectStatus().isOk()
  }
    
  def "when TLSv1.3 allowed cipher suite used then accepted"() {
        given:
        def client = getHttpClient(TestConstants.TLSV1_3, List.of("TLS_CHACHA20_POLY1305_SHA256"))
        expect:
        client
                .get()
                .uri("/posts/${TestConstants.TEST_UUID}")
                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .exchange()
                .expectStatus().isOk()
  }

Logs

tls12.log tls13.log

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 17 (7 by maintainers)

Most upvoted comments

@wilkinsona Thank you so much! I was pulling my hair out. You are absolutely correct.

I’ve set a debug point in Netty’s JdkSslContext and it seems the ciphers configured with the application properties are taken into account. The line you’re seeing in the logs is really Netty logging the default ones.

@optimisticninja WebClient doesn’t deal directly with the cipher suites or the TLS setup in general, so if you’re encountering such an issue, chances are you can reproduce the same with a vanilla HttpClient and report the issue directly to reactor-netty. Another way to consider such a problem is to try and reproduce it with another connector, like Jetty client.

Just realized that after reviewing tests stacktrace. Thank you, crawling their issues looking for a dupe.