Julien Berthoud
Julien Berthoud

Reputation: 769

mutualTLS with SpringBoot SslBundles and RestTemplate

I have a SpringBoot Application (client) that makes REST calls to an external service (server). The communication between client and server should be secured with mutual TLS. So in this setting we need a client certificate in our keystore and a CA certificate for the server in our truststore.

When I importe this certificate material in Postman, i can successfully make requests. Meaning: the certificates are valid.

Nevertheless so far, I couldn't make it work in SpringBoot. I'd like to take advantage of the SslBundles introduced by SpringBoot 3.1

I defined a bundle with both keystore and truststore:

spring:
  ssl:
    bundle:
      jks:
        mySslBundle:
          keystore:
            location: "classpath:path/to/clientCert.p12"
            password: "PW"
            type: "PKCS12"
          truststore:
            location: "classpath:path/to/serverCA.p12"
            password: "PW"
            type: "PKCS12"

then I can bind this bundle to the RestTemplate:

@Configuration
public class RestTemplateConfig {

  @Bean(name = "fooRestTemplate")
  public RestTemplate createFooRestTemplate(RestTemplateBuilder restTemplateBuilder,
      SslBundles sslBundles) {
    return restTemplateBuilder
        .setSslBundle(sslBundles.getBundle("mySslBundle"))
        .build();
  }

}

When the client sends request to the server within the application, I get following error:

Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

In Postman, i had to load the server cert as .pem file. In my SpringBoot app, i converted the .pem file into a .p12 with openssl. I did that so that both client cert and server cert are p12 file and can be imported in the same sslBunde. Is this the right approach to import keystore and trustore in the same bundle ?

Any clue appreciated.

Upvotes: 0

Views: 2400

Answers (2)

Julien Berthoud
Julien Berthoud

Reputation: 769

As it was suggested in the comments, using keytool instead of openssl for the conversion of the .crt server cert into a .p12 solved my problem.

So, yes it is OK to pack keystore and trustore in the same bundle as I did, and we should use keytool if a conversion is needed to produce the .p12 file.

Upvotes: 0

Zadra
Zadra

Reputation: 65

I have been working with almost the same issue and I've come up with following solution. There should be two bundles - one for client and one for server.

spring:
  ssl:
    bundle:
      jks:
        mySslBundleClient:
          keystore:
            location: "classpath:path/to/clientCert.p12"
            password: "PW"
            type: "PKCS12"
        mySslBundleServer:
          truststore:
            location: "classpath:path/to/serverCA.p12"
            password: "PW"
            type: "PKCS12"

Then for RestTemplate use mySslBundleServer

@Configuration
public class RestTemplateConfig {

  @Bean(name = "fooRestTemplate")
  public RestTemplate createFooRestTemplate(RestTemplateBuilder restTemplateBuilder,
      SslBundles sslBundles) {
    return restTemplateBuilder
        .setSslBundle(sslBundles.getBundle("mySslBundleServer"))
        .build();
  }
}

Additionally with such a configuration it is possible to use one certificate for both bundles.

Upvotes: 1

Related Questions