Wednesday, January 22, 2020

How to install free ssl certificate in spring boot using Let's Encrypt


As we know ssl provides the extra layer of security. Every packet transferred between client and server is encrypted using public or private key cryptography. Now a days everyone ensuring to protect their web application through ssl certificate. If you have developed your web application by using Spring then you are at right place. Here you will learn how to install ssl certificate without paying anything.

How to use install free genuine ssl certificate in spring boot application using let's encrypt


There are multiple ways to generate ssl certificates. Even Java also has provided a tool(keytool). If you will use keytool then you can enable https but still you will see Not Secure in the browser URL like this.

Not Secure


Hence we are here to make this as secure with green color https URL. To make this green https, we will use Let's Encrypt. Let's Encrypt is a non-profit certificate authority run by Internet Security Research Group that provides X.509 certificates for Transport Layer Security encryption at no charge. So Let's follow the steps.

Step 1:
Stop the application or server running on the port 80 or 443. You can check whether any application or server running or not on a particular port by using lsof command.
lsof -i :8080

To stop the application or server, you can use kill command.
kill -9 pid

Step 2:
You need to install the certbot on your server. You can open the server terminal by using ssh command.
ssh alt@xxx.xxx.xxx.xxx
where xxx is your server ip address. Now use this command to install certbot if you have Ubuntu operating system.
sudo apt-get update -y && sudo apt-get upgrade -y
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache

Step 3:
Now generate the ssl certificate by using the following command.
certbot certonly -a standalone -d api.example.com
where api.example.com is your domain name. This will generate the 4 .pem files inside etc/letsencrypt/live/api.example.com-0001/.
To goto this directory, use this command.
cd /
cd etc/letsencrypt/live/api.example.com-0001/
To see the files in the current directory use the ls command.
ls
This will show the following files list.
cert.pem  chain.pem  fullchain.pem  privkey.pem  README

Step 4:
As we know Spring supports .p12 file for ssl certification. Hence we need to convert the .pem files into .p12 file. To generate PKCS12 file from PEM files we shall have to use openssl command.
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out api_example_com.p12 -name myalias -CAfile chain.pem -caname root
Hint:
-out will the converted file name
-name will be your alias name

This will ask to enter password. After entering the password, again it will ask the password. You will have to enter the password 2 times.

Step 5:
Finally, it will generate the api_example_com.p12 file in the current directory. Now you need to copy this file in Spring Boot Maven project resource directory(src/main/resources/). To copy the file from server location to local machine, you can scp command but I will recommend to first copy the file to your ubuntu home location because there may be a lot of users present that OS.
cp api_example_com.p12 /home/myusername/
exit
exit
Now you are in local machine terminal. From here you need to copy the file from server machine home location to your local machine.
scp alt@xxx.xxx.xxx.xxx:api_example_com.p12 .
Hint: Here . means current directory. You can change it your appropriate directory. This will be downloaded into your home directory.

Step 6:
Now copy this(api_example_com.p12) file and paste in src/main/resources of your Spring Boot project. Now do some changes in your application.properties file
server.ssl.enabled=true
server.ssl.key-store=classpath:api_example_com.p12
server.ssl.key-store-password=mypassword
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=myalias
http.port=80
server.port=443

Step 7:
Here you need to take special care. After saving this configuration in your application.properties file, if you start the server locally, it will fail to start. Because the .p12 has mapped to your ip xxx.xxx.xxx.xxx and your current ip is 127.0.0.1 that is localhost. Hence only this will start on your server. To avoid this happening, you can use profile concept of Spring. Hence you need to create another property file ie application-prod.properties then cut and paste those ssl configuration in application-prod.properties file and remove from application.properties file.
You need to write one more line in application.properties file
spring.profiles.active=prod
Now if you want to start the server locally then comment this and start.
#spring.profiles.active=prod
It will start locally without ssl but when you want to start the server on server machine then you need to uncomment this config.

Step 8:
This is an optional step but I will recommend to do. In this step you need to write a config class
that will redirect every request that is coming via http to https.
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Profile("prod")
@Configuration
public class TomcatConfig {

@Value("${http.port}")
private int httpPort;

@Bean
public EmbeddedServletContainerFactory servletContainer() {
 TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
  @Override
  protected void postProcessContext(Context context) {
   SecurityConstraint securityConstraint = new SecurityConstraint();
   securityConstraint.setUserConstraint("CONFIDENTIAL");
   SecurityCollection collection = new SecurityCollection();
   collection.addPattern("/*");
   securityConstraint.addCollection(collection);
   context.addConstraint(securityConstraint);
  }
 };
 tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
 return tomcat;
}

 private Connector initiateHttpConnector() {
  Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
  connector.setScheme("http");
  connector.setPort(httpPort);
  connector.setSecure(false);
  connector.setRedirectPort(8443);
  return connector;
 }
}

Congrats! You are done. Feel free to comment, if you have any doubt.


Share this

8 Responses to "How to install free ssl certificate in spring boot using Let's Encrypt"

  1. เค—เคœเคฌ เคญाเคˆ

    ReplyDelete
  2. If it were necessary to enable http 2, how would I do it?

    ReplyDelete
    Replies
    1. Can you elaborate your question pls?
      By the way if you are asking to make all the request mandatory to be https then step8 will work.

      Delete
  3. Good article on SSL configuration in spring boot.

    ReplyDelete
  4. Awsm work good work....on SSL configuration....๐Ÿ‘Œ๐Ÿป๐Ÿ‘Œ๐Ÿป๐Ÿ‘Œ๐Ÿป๐Ÿ‘Œ๐Ÿป

    ReplyDelete