How can I set up a letsencrypt SSL certificate and use it in a Spring Boot application?
JavaSpringSslSpring BootLets EncryptJava Problem Overview
I'm new to securing a server so I don't really know much about this but I need to get my Spring Boot Application that is running on a Digital Ocean Droplet to use HTTPS.
My idea is to register a letsencrypt certificate and then tell Spring to use that.
However, I have no idea how to do that.
Thanks.
Java Solutions
Solution 1 - Java
I wrote 2 blog posts about Let's Encrypt and Spring Boot.
- Issuing a certificate. Spring Boot Application Secured by Let’s Encrypt Certificate
- Renewing a certificate. Let’s Encrypt Certificate Renewal: for Spring Boot
In a nutshell, steps are as follows:
-
Pulling the Let's Encrypt client (certbot).
-
Generating a certificate for your domain (e.g. example.com)
./certbot-auto certonly -a standalone -d example.com -d www.example.com
Things are generated in /etc/letsencrypt/live/example.com
. Spring Boot expects PKCS#12 formatted file. It means that you must convert the keys to a PKCS#12 keystore (e.g. using OpenSSL). As follows:
- Open
/etc/letsencrypt/live/example.com
directory. -
`openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root`
The file keystore.p12 with PKCS12 is now generated in /etc/letsencrypt/live/example.com
.
It's time to configure your Spring Boot application. Open the application.properties file and put following properties there:
server.port=8443
security.require-ssl=true
server.ssl.key-store=/etc/letsencrypt/live/example.com/keystore.p12
server.ssl.key-store-password=<your-password>
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=tomcat
Read my blog post for further details and remarks.
Solution 2 - Java
Step 1: Download certbot from git
You need to fetch the source code of Let's Encrypt on your server which your domain address is pointing to. This step may take a couple minutes.
> $ git clone https://github.com/certbot/certbot > > $ cd certbot > > $ ./certbot-auto --help
Remark: Python 2.7.8 (or above) should be installed beforehand.
Step2: generates certificates and a private key
By executing following command in your terminal, Let's Encrypt generates certificates and a private key for you.
> $ ./certbot-auto certonly -a standalone
>
> -d example.com -d example.com
Remark:Keys are generated in /etc/letsencrypt/live/example.com directory
Step3: Generate PKCS12 Files From PEM Files
To convert the PEM files to PKCS12 version: Go to /etc/letsencrypt/live/example.com convert the keys to PKCS12 using OpenSSL in the terminal as follows.
> $ openssl pkcs12 -export -in fullchain.pem
>
> -inkey privkey.pem
>
> -out keystore.p12
>
> -name tomcat
>
> -CAfile chain.pem
>
> -caname root
Enter Export Password:
Verifying - Enter Export Password:
(Note:- Write single line at a time and press enter)
Step4: Configuration of Spring Boot Application
Open your 'application.properties' Put this configuration there.
> server.port=8443 security.require-ssl=true > > server.ssl.key-store=/etc/letsencrypt/live/example.com/keystore.p12 > > server.ssl.key-store-password= password > > server.ssl.keyStoreType= PKCS12 > > server.ssl.keyAlias= tomcat
Solution 3 - Java
Another option is to use Spring Boot Starter ACME:
https://github.com/creactiviti/spring-boot-starter-acme
ACME (Automatic Certificate Management Environment) it the protocol used by LetsEncrypt to automatically issue certs.
Solution 4 - Java
For spring boot webflux the configuration of properties changed
server.port=443
server.ssl.enabled=true//the changed line
server.ssl.keyAlias=netty
server.ssl.key-store=path
server.ssl.key-store-password=password
server.ssl.keyStoreType=PKCS12
Solution 5 - Java
letsencrypt-tomcat queries and refreshes certs via Let's encrypt at runtime (no restarts needed).
It works with standalone and embedded Tomcat as well as Spring Boot.
It's packaged into a Docker image, allowing for easy reuse. The image contains:
- dehydrated to manage certs via Let’s Encrypt,
- tomcat-reloading-connector for hot reloading certs at runtime after renewal,
- an init system (dumb-init) for properly handling tomcat and dehydrated processes,
- an entrypoint script that starts up tomcat and dehydrated as well as
- a pre-compiled version of Apache Portable Runtime (APR) and JNI wrappers for APR used by Tomcat (libtcnative), so tomcat delivers the best TLS performance possible.
Read this blog post to learn how to use it with your application and more about the technical details.
Solution 6 - Java
I've created a small library in pure Java that allows embedded Tomcat in Spring-Boot to obtain and keep Lets Encrypt certificate fresh automatically: Spring-Boot LetsEncrypt helper
It is just one Java file + dependencies on ACME4J/BouncyCastle, so that one can re-use it as a code
In short, it does the following:
- On application start it creates KeyStore as defined in your
server.ssl
properties if it does not exist yet (and adds self-signed expired cert there). - Registers Tomcat connector on port 80 for HTTP-01 ACME challenge from LetsEncrypt
- Launches thread that checks if the certificate in KeyStore is outdated or missing
- If the certificate is outdated/missing it issues an order to LetsEncrypt and passes HTTP-01 ACME challenge on port 80.
- After passing the challenge it stores the certificate into KeyStore defined in
server.ssl
and issuesreloadSslHostConfigs
on Tomcat HTTPS enabled connector
With these steps, the entire LetsEncrypt certificate lifecycle from the issuing to update is covered within Java application itself without any non-Java 3rd parties
Solution 7 - Java
- Get an SSL certificate from letsencrypt
- Add it into a keystore using the
keytool
command in Java - Configure your Spring application to use the keystore generated above
The file should look like:
server.port = 8443
server.ssl.key-store = classpath:sample.jks
server.ssl.key-store-password = secret
server.ssl.key-password = password