Let's Encrypt is a non-profit organisation that hands out certificates. They run on donations so if you can...

Using let's encrypt for an embedded Jetty web server.

This page is for linux, windows will be similar but YMMV.

You will need to run this on the live web server as certbot will download a text and Let's Encrypt will look for that file to make sure you are the owner of the web site. Let's Encrypt gives you a three month certificate so you'll need to run this regularly (the get_cert.sh script not the install obviously). I do mine via cron.

First you will need to install certbot and openssl. They are both in Ubuntu's repositories or you can download it from here for certbot and here for openssl. The software manager might find them so you can avoid the command line options.

sudo apt install certbot

sudo apt install openssl

Next you need to generate a key pair, if you haven't already. This will ask for a password, you'll need to remember it for later.

keytool -genkeypair -alias domain.com.au -keyalg RSA -keystore keystore.jks

Then you need to request a certificate and import it into the keystore. Java keytool doesn't understand pem etc, so there is a conversion line here.

This is a bash script to run the request to get a new certificate. This is set to run monthly via cron.

For the initial run you do not need and, probably, should not use the --force-renew option.

The certbit line will return four files required for numerous web servers (cert.pem, chain.pem, fullchain.pem, and privkey.pem) for embedded jetty we only need to two (fullchain.pem and privkey.pem).

The CERT_PASSWORD is only required for the length of the script. Without it the script will require you to confirm that you don't want a password.

The KEYSTORE_PASSWORD is required and is the password you used to create the key pair above.

Deleting and adding the certificate will allow this to run automatically, if you skip the delete the script will stop and ask you if you want to replace the certificate.

Put this into a bash script file. I've called it get_cert.sh which can only be run by root.

#!/bin/bash
if [ "$USER" != "root" ]
  then
  echo "Certificates can only be retrieved by root."
  exit 2
fi

KEYSTORE_PASSWORD=$1
CERT_PASSWORD=$2

# Change into the keystore folder where keystore.jks resides
cd /keystore/folder

echo `date` > cert.log

# Using certbot request a new certificate (note --force-renew is needed for subsequent runs)
certbot certonly --force-renew --webroot -w /http/web/resources/root/ -d domain.name.com 2>&1 >> cert.log 

# Use openssl to convert and merge the privkey.pen and fullchain.pem into a cert.p12
openssl pkcs12 -export -out cert.p12 -inkey /etc/letsencrypt/live/domain.name.com/privkey.pem -in /etc/letsencrypt/live/domain.name.com/fullchain.pem -name "domain.name.com" -password pass:$CERT_PASSWORD 2>&1 >> cert.log

# Using keytool delete the older certificate so it won't ask if you want to overwrite
keytool -delete -keystore keystore.jks -alias domain.name.com -storepass $KEYSTORE_PASSWORD 2>&1 >> cert.log

# Using keytool add the new certificate
keytool -importkeystore -srckeystore cert.p12 -srcstoretype pkcs12 -srcstorepass $CERT_PASSWORD -destkeystore keystore.jks -deststorepass $KEYSTORE_PASSWORD 2>&1 >> cert.log

# Restart the web service
service webd restart

echo `date` >> cert.log

Add get_cert.sh to the crontab of root.

0 0 1 * * /usr/local/web/keystore/get_cert.sh KEY_STORE_PASSWORD CERT_PASSWORD