Configuring SSL Certificate Content in Application.yml in Spring Boot

Photo by Luke Peters on Unsplash

Configuring SSL Certificate Content in Application.yml in Spring Boot

Securing your Spring Boot application with SSL/TLS is crucial for protecting data in transit. While it's common to reference certificate files directly, there are scenarios where you might want to embed the certificate content within your application.yml file. This blog post will guide you through the process of configuring your .crt file content directly in your Application.yml file.

Why Embed Certificate Content?

Before we dive into the how-to, let's briefly discuss why you might want to embed certificate content in your configuration file:

  1. Containerization: When deploying in containers, it can be easier to inject certificate content as environment variables rather than mounting certificate files.

  2. Cloud Environments: Some cloud platforms prefer configuration over file management for security credentials.

  3. Simplified Deployment: Embedding certificates can reduce the number of files you need to manage during deployment.

Step-by-Step Guide

1. Prepare Your Certificate

First, you need to convert your .crt file to a Base64-encoded string. You can do this using the following command:

base64 -w 0 your_certificate.crt > certificate_base64.txt

This command will output the Base64-encoded content of your certificate to a file named certificate_base64.txt.

2. Configure Application.yml

Now, let's add the certificate content to your application.yml file. Here's an example of how to structure it:

server:
  port: 8443
  ssl:
    enabled: true
    key-store-type: PKCS12
    key-store: classpath:keystore.p12
    key-store-password: your_keystore_password
    key-alias: your_key_alias

custom:
  ssl:
    certificate: |
      -----BEGIN CERTIFICATE-----
      MIIDXTCCAkWgAwIBAgIJAJ5hJlev4JCIMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
      BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
      ...
      (Your Base64-encoded certificate content goes here)
      ...
      -----END CERTIFICATE-----

In this configuration:

  • We're setting up the standard SSL configuration for Spring Boot.

  • We've added a custom section custom.ssl.certificate where we paste the content of our certificate.

3. Using the Certificate in Your Application

To use this certificate in your application, you'll need to create a custom configuration class. Here's an example:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "custom.ssl")
public class SslConfig {
    private String certificate;

    // Getter and setter for certificate
    public String getCertificate() {
        return certificate;
    }

    public void setCertificate(String certificate) {
        this.certificate = certificate;
    }
}

This class will automatically bind the certificate content from your application.yml to the certificate field.

4. Creating a TrustManager

Now that you have access to the certificate content, you can create a TrustManager to use it:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.*;
import java.io.ByteArrayInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

@Configuration
public class SslTrustManagerConfig {

    @Autowired
    private SslConfig sslConfig;

    @Bean
    public TrustManager[] trustManagers() throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate) cf.generateCertificate(
            new ByteArrayInputStream(sslConfig.getCertificate().getBytes())
        );

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null);
        ks.setCertificateEntry("cert", cert);
        tmf.init(ks);

        return tmf.getTrustManagers();
    }
}

This configuration creates a TrustManager using the certificate content from your application.yml.

Best Practices and Considerations

  1. Security: Be cautious about storing sensitive information like certificates in configuration files. Ensure your application.yml is properly secured and not committed to version control.

  2. Environment Variables: For added security, consider using environment variables to inject the certificate content at runtime:

     custom:
       ssl:
         certificate: ${SSL_CERTIFICATE}
    
  3. Rotation: Remember that embedding certificates in your configuration makes rotation more challenging. Have a strategy in place for updating certificates.

  4. Multiple Certificates: If you need to configure multiple certificates, you can use a YAML list:

     custom:
       ssl:
         certificates:
           - |
             -----BEGIN CERTIFICATE-----
             (Certificate 1 content)
             -----END CERTIFICATE-----
           - |
             -----BEGIN CERTIFICATE-----
             (Certificate 2 content)
             -----END CERTIFICATE-----
    
  5. Validation: Always validate that your application correctly uses the embedded certificate by testing your SSL/TLS connections.

Conclusion

Configuring SSL certificate content directly in your application.yml file can simplify deployment in certain scenarios, especially in containerized or cloud environments. By following this guide, you can embed your certificate content securely and use it effectively in your Spring Boot application.

Remember to always follow security best practices and consider the trade-offs between configuration flexibility and security when deciding how to manage your SSL certificates.

Did you find this article valuable?

Support Nikhil Soman Sahu by becoming a sponsor. Any amount is appreciated!