HTTPS using Self-Signed Certificate in Spring Boot

1. Overview

In this tutorial, we’re going to illustrate step by step an example of enabling HTTPS in a Spring Boot application.

We’ll generate a self-signed certificate and configure it in a sample app. For more details on Spring Boot projects, we can refer to a bunch of resources here.

Further reading:

Spring Boot Security Auto-Configuration

A quick and practical guide to Spring Boot’s default Spring Security configuration.

Read more

Introduction to Java Config for Spring Security

A quick and practical guide to Java Config for Spring Security

Read more

2. Generating a Self-Signed Certificate

Before getting started, we’ll create a self-signed certificate. We’ll use either of the following certificate formats:

  • PKCS12: Public Key Cryptographic Standards is a password protected format that can contain multiple certificates and keys; it’s an industry-wide used format

  • JKS: Java KeyStore is similar to PKCS12; it’s a proprietary format and is limited to the Java environment.

We can use either of keytool or OpenSSL tools to generate the certificates from the command line. Keytool is shipped with Java Runtime Environment and OpenSSL could be downloaded from here.

Let’s use keytool for our demonstration.

2.1. Generating a Keystore

Now we’ll create a set of cryptographic keys and store it in a keystore.

We can use the following command to generate our PKCS12 keystore format:

keytool -genkeypair -alias baeldung -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore baeldung.p12 -validity 3650

We can store as many numbers of key-pair in the same keystore each identified by a unique alias.

For generating our keystore in a JKS format, we can use the following command:

keytool -genkeypair -alias baeldung -keyalg RSA -keysize 2048 -keystore baeldung.jks -validity 3650

It is recommended to use the PKCS12 format which is an industry standard format. So in case we already have a JKS keystore, we can convert it to PKCS12 format using the following command:

keytool -importkeystore -srckeystore baeldung.jks -destkeystore baeldung.p12 -deststoretype pkcs12

We’ll have to provide the source keystore password and also set a new keystore password. The alias and keystore password will be needed later.

3. Enabling HTTPS in Spring Boot

Spring Boot provides a set of a declarative server.ssl.* properties. We’ll configure those properties in our sample application to configure HTTPS.

We’ll start from a simple Spring Boot application with Spring Security containing a welcome page handled by the “/welcome” endpoint.

We’ll copy the file named “baeldung.p12″ generated from the previous step into the “src/main/resources/keystore” directory.

3.1. Configuring SSL Properties

Now, we’ll configure the SSL related properties:

# The format used for the keystore. It could be set to JKS in case it is a JKS file
server.ssl.key-store-type=PKCS12
# The path to the keystore containing the certificate
server.ssl.key-store=classpath:keystore/baeldung.p12
# The password used to generate the certificate
server.ssl.key-store-password=password
# The alias mapped to the certificate
server.ssl.key-alias=baeldung

Since we are using Spring Security enabled application, let’s configure it to accept only HTTPS requests:

security.require-ssl=true

4. Invoking an HTTPS URL

Now that we have enabled HTTPS in our application, let’s move on into the client and let’s explore how to invoke an HTTPS endpoint with the self-signed certificate.

First, we need to create a trust store. As we have generated a PKCS12 file, we can use the same as the trust store.  Let’s define new properties for the trust store details:

#trust store location
trust.store=classpath:keystore/baeldung.p12
#trust store password
trust.store.password=password

Now we need to prepare an SSLContext with the trust store and create a customized RestTemplate:

RestTemplate restTemplate() throws Exception {
    SSLContext sslContext = new SSLContextBuilder()
      .loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray())
      .build();
    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
    HttpClient httpClient = HttpClients.custom()
      .setSSLSocketFactory(socketFactory)
      .build();
    HttpComponentsClientHttpRequestFactory factory =
      new HttpComponentsClientHttpRequestFactory(httpClient);
    return new RestTemplate(factory);
}

For the sake of the demo, let’s make sure Spring Security allows any incoming requests:

protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .antMatchers("/**")
      .permitAll();
}

Finally, we can make a call to the HTTPS endpoint:

@Test
public void whenGETanHTTPSResource_thenCorrectResponse() throws Exception {
    ResponseEntity<String> response =
      restTemplate().getForEntity(WELCOME_URL, String.class, Collections.emptyMap());

    assertEquals("<h1>Welcome to Secured Site</h1>", response.getBody());
    assertEquals(HttpStatus.OK, response.getStatusCode());
}

5. Conclusion

In the tutorial, we learned about how to generate a self-signed certificate to enable HTTPS in a Spring Boot application. We also learned how to invoke an HTTPS-enabled endpoint.

As always, we can find the complete source code over on GitHub repository.

Finally, to run the code sample, we need to un-comment the following start-class property in the pom.xml:

<start-class>org.baeldung.ssl.HttpsEnabledApplication</start-class>

Leave a Reply

Your email address will not be published.