Kyle Heller
Certificate Management in SPRING For BEGINNERS
When setting up secure communication for a website or application, HTTPS/TLS certificates play a crucial role. The fact they are so crucial and ubiquitous on the modern web can make it especially frustrating when things aren't working the way it seems like they should. I want to help you in your time of need so I made this guide to help you step by step, whether creating a self-signed certificate, or third party verified certificate to use in your Spring Boot application. I hope this helps clear up the process and the components involved!
What is a CSR?
CSR (Certificate Signing Request): A CSR is a block of encoded text that contains information about the entity requesting a certificate, such as the organization name and domain. It also includes the public key of the key pair generated by the requester.
Purpose: The CSR is sent to a Certificate Authority (CA) to apply for a digital identity certificate. It proves to the CA that the requester controls the private key associated with the public key in the CSR. The CA uses the CSR to create a certificate that browsers and clients can trust.
What is a Private Key?
Private Key: Part of a key pair used in public-key cryptography, the private key remains securely stored on the server or application that generates the CSR. It's never shared or transmitted.
Purpose: The private key is used to decrypt information encrypted with the corresponding public key. It's also used to sign data, ensuring that messages and transactions are authentic and come from the expected source.
What You Receive from a Third-Party Certificate Provider
After submitting your CSR to a CA, you'll receive several important files. Understanding what these files are and their purpose is critical for correctly configuring your server or application for SSL/TLS:
1. Signed Certificate: This is your SSL/TLS certificate, signed by the CA. It's sometimes provided in formats like `.crt` or `.pem`.
Purpose: This certificate contains your domain name (or names, if you've requested a SAN certificate) and your public key. It serves as a form of identification for your website or application.
2. Intermediate Certificates: These certificates establish a chain of trust from your SSL/TLS certificate to the CA's root certificate.
Purpose: Intermediate certificates link your SSL/TLS certificate to a root CA that browsers inherently trust. This chain is essential for browsers and clients to trust the authenticity of your certificate.
3. Root Certificate: Occasionally, you might also receive the root certificate, though typically, your server or application doesn't need it because client systems already trust these root certificates.
Purpose: The root certificate is the topmost certificate in the chain of trust. While not usually required for server configuration, it's fundamental to the trust model of SSL/TLS.
Configuring Your Server or Application
With these components, you're ready to configure your server or application:
1. Install the Signed Certificate: This involves placing the signed certificate file in the appropriate location and configuring your server or application to use it for SSL/TLS connections.
2. Include Intermediate Certificates: Ensure that your configuration also includes the intermediate certificates. This might involve concatenating certificate files or specifying multiple certificate file paths, depending on your server's requirements.
3. Link to the Private Key: Your server or application configuration must reference the private key generated when you created your CSR. This key is used during the SSL/TLS handshake to establish secure connections.
SSL/TLS Certificate Management with Keytool
Now that you have the basic concepts down lets go ahead and put it into action. Here's how to generate a third party verified cert step by step using Java's `keytool`.
Java includes the keytool utility in its releases. We use it to manage keys and certificates and store them in a keystore. The keytool command allows us to create self-signed certificates, generate CSRs, and show information about the contents of the created keystores.
You can find the utility in the bin folder of your Java install and interact with it through your operating systems CLI.
1. Create a Java KeyStore (JKS) and Generate Key Pair
First, generate a key pair (public and private keys). This step also creates a new JKS if it doesn't already exist.
keytool -genkeypair -alias server -keyalg RSA -keysize 2048 -keystore mykeystore.jks -validity 365 -dname "CN=www.example.com, OU=Example, O=Example, L=City, ST=State, C=US" -storepass changeit
This command does several things:
- `-genkeypair` generates the key pair.
- `-alias server` sets the alias for the key pair.
- `-keyalg RSA` specifies the RSA algorithm.
- `-keysize 2048` sets the key size.
- `-keystore mykeystore.jks` names the keystore file.
- `-validity 365` sets the certificate's validity period.
- `-dname` specifies the distinguished name used for the certificate.
- `-storepass changeit` sets the keystore password.
If you omit the -dname option when using keytool -genkeypair to generate a key pair, keytool will interactively prompt you to enter the necessary information for the distinguished name (DN) fields. Some versions of keytool are going to ask "What is your first and last name?" but this should be your sites domain name.
You can also ommit the validity parameter to use the default 90 days.
2. Generate a Certificate Signing Request (CSR)
Next, generate a CSR using the key pair in your keystore.
keytool -certreq -alias server -file mycsr.csr -keystore mykeystore.jks -storepass changeit
- `-certreq` indicates you're generating a CSR.
- `-alias server` specifies which key pair to use.
- `-file mycsr.csr` names the CSR file.
- `-keystore mykeystore.jks` and `-storepass changeit` provide keystore details.
3. Importing the CA's Response and Intermediate Certificates
After submitting your CSR and receiving your certificates from the CA, import them back into your keystore.
Import the Root CA Certificate (if provided and not already trusted)
keytool -import -alias root -file rootCA.crt -keystore mykeystore.jks -storepass changeit
Import the Intermediate Certificate(s)
If you received one or more intermediate certificates, import them next.
keytool -import -alias intermediate1 -file intermediateCA1.crt -keystore mykeystore.jks -storepass changeit
Repeat for any additional intermediate certificates, ensuring each has a unique alias. When I got my CA bundle it had more than one cert in a single file. When I imported the bundle as a single file it only imported the first so be careful here, if you need you can split them into two separate files to import. (Just create two text files with .pem extensions)
Import Your Signed Certificate
Finally, import the signed certificate associated with your private key.
keytool -import -alias server -file signedCertificate.crt -keystore mykeystore.jks -storepass changeit
- `-import` instructs `keytool` to import the certificate.
- `-alias server` matches the alias used during the key pair generation.
- `-file signedCertificate.crt` is your CA-signed certificate.
With your CA-signed certificate (and any intermediates) imported into your JKS, your server or application is now ready to use this keystore for secure communications. Ensure your server or application is configured to point to `mykeystore.jks` and uses the correct password.
Importing into Spring
In your Spring Boot application, you need to configure application.properties or application.yml to use the keystore and enable HTTPS.
application.properties:
# Server port
server.port=443
# Keystore configuration
server.ssl.key-store=classpath:mykeystore.jks
server.ssl.key-store-password=<password>
server.ssl.keyStoreType=JKS
server.ssl.keyAlias=server
You can also link to places other than the classpath with file:/
With that you should be able to fire up your Spring app and see that Tomcat is fired up and listening on port 443 utilizing your newly generated cert!
If you run into issues and can't connect to your site over HTTPS be patient. There are quite a few things that might go wrong at this step. First verify that Java is listening on the required port, next make sure that you can access the remote port from your client machine. If there are any issues there check firewall configurations and make sure traffic is allowed on the specified ports.
If you are still seeing issues you might also need to check for things like compatibility of cipher suites and cryptographic algorithms. Different versions of Spring might use different standards.
Lastly in my case I hit a snag using a newer version of Java with an older version of Spring. If all else fails you might try with the latest version of Spring, especially if your project is using a version that's out of date.
Final Thoughts
Managing SSL/TLS certificates involves generating key pairs, creating CSR, and handling certificates issued by CAs. Understanding each component's role—from the private key and CSR to the signed certificate and intermediate certificates—is crucial for establishing a secure, trusted connection for your website or application.
Remember, always keep your private key secure and follow best practices for certificate renewal and management to maintain your site's security and trustworthiness. When specifying secrets in code that is being published publicly, utilize variable references to files that are not uploaded to that repository.
I'll see you in the next one!