{"id":4558,"date":"2018-09-27T00:11:53","date_gmt":"2018-09-27T03:11:53","guid":{"rendered":"https:\/\/blog.clusterweb.com.br\/?p=4558"},"modified":"2018-09-27T00:13:31","modified_gmt":"2018-09-27T03:13:31","slug":"spring-boot-secured-by-lets-encrypt","status":"publish","type":"post","link":"https:\/\/blog.clusterweb.com.br\/?p=4558","title":{"rendered":"Spring Boot Secured By Let&#8217;s Encrypt"},"content":{"rendered":"<p>In this article, we want to know how we can (1) generate a valid certificate for free; (2) configure a Spring Boot app with it; and lastly (3) how to renew it when it expires.<\/p>\n<p>In my previous\u00a0blog post, we became familiar with configuration of an\u00a0Spring Boot Application\u00a0with a self-signed certificate. Self-signed certificates are good for specific purposes such as test and development. But, if one needs to ship his application to production, certificates should be signed by known and legitimate Certificate Authorities (CA).<\/p>\n<p>These types of certificates are usually expensive. If you want to harden\u00a0your application with TLS, you need to purchase one of them. The price and complex configuration of application servers made a barrier for many web applications to use secure connections.<\/p>\n<p>In the\u00a0post-Snowden era, no one needs to convince us that having secure connection using HTTPS is a must. There are lots of efforts to increase awareness of developers and IT administrators to employ such technologies for every single website they make. But how?<\/p>\n<p><a href=\"https:\/\/letsencrypt.org\/\" rel=\"nofollow\">Let&#8217;s Encrypt<\/a>\u00a0projects aims at bringing HTTPS to World Wide Web not only for free but also with the simplest way of configuration.<\/p>\n<p><!--more--><\/p>\n<p>In this article, we cover:<\/p>\n<ul>\n<li>Issuing a certificate and Spring\u00a0Boot intergration\n<ol>\n<li>How to generate certificates with Let&#8217;s Encrypt?<\/li>\n<li>How to generate PCKS#12 files from PEM files?<\/li>\n<li>Configuration of your Spring Boot application<\/li>\n<\/ol>\n<\/li>\n<li>Renewing an (about-to) expired certificate\n<ol>\n<li>Renewal process<\/li>\n<li>Preparation for Spring Boot<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<h2>How to Generate Certificates With Let&#8217;s Encrypt<\/h2>\n<p>Let&#8217;s Encrypt has several\u00a0plugins for some application servers such as Apache and Nginx. In this section, as\u00a0our target is Spring Boot Application (with an embedded Jetty\/Tomcat), we just generate the certificates and later on integrate with our application.<\/p>\n<p>If you&#8217;re using a firewall or any other security mechanism at your server or Cloud provider, you should relax it for a couple of minutes &#8211; specially port 80 and port 443.<\/p>\n<p>Port 80 should be open and free to use as Let&#8217;s Encrypt runs a small http server behind the scene to prove whether you control your domain address (ACME protocol).<\/p>\n<ol>\n<li>You need to fetch the source code of\u00a0Let&#8217;s Encrypt\u00a0on your server which your domain address is pointing to.\u00a0This step may take a couple minutes.\n<div class=\"CodeMirror cm-s-default\">\n<div class=\"CodeMirror-scroll\">\n<div class=\"CodeMirror-sizer\">\n<div>\n<div class=\"CodeMirror-lines\">\n<div>\n<div class=\"CodeMirror-code\">\n<div>\n<div class=\"CodeMirror-gutter-wrapper\">\n<div class=\"CodeMirror-linenumber CodeMirror-gutter-elt\" data-line-number=\"1\"><\/div>\n<\/div>\n<pre><span class=\"cm-def\">$ git<\/span> clone https:\/\/github.com\/certbot\/certbot<\/pre>\n<\/div>\n<div>\n<div class=\"CodeMirror-gutter-wrapper\">\n<div class=\"CodeMirror-linenumber CodeMirror-gutter-elt\" data-line-number=\"2\"><\/div>\n<\/div>\n<pre><span class=\"cm-def\">$ cd<\/span> certbot<\/pre>\n<\/div>\n<div>\n<div class=\"CodeMirror-gutter-wrapper\">\n<div class=\"CodeMirror-linenumber CodeMirror-gutter-elt\" data-line-number=\"3\"><\/div>\n<\/div>\n<pre><span class=\"cm-def\">$ <\/span>.\/certbot-auto <span class=\"cm-attribute\">--help<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"CodeMirror-gutters\">\n<div class=\"CodeMirror-gutter CodeMirror-linenumbers\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><em><strong>Remark:<\/strong><\/em>\u00a0Python 2.7.8 (or above) should be installed beforehand.<\/li>\n<li>By executing following command\u00a0in your terminal, Let&#8217;s Encrypt generates certificates and a\u00a0private key for you.\n<div class=\"CodeMirror cm-s-default\">\n<div class=\"CodeMirror-scroll\">\n<div class=\"CodeMirror-sizer\">\n<div class=\"CodeMirror-lines\">\n<div class=\"CodeMirror-code\">\n<div>\n<div class=\"CodeMirror-gutter-wrapper\">\n<div class=\"CodeMirror-linenumber CodeMirror-gutter-elt\" data-line-number=\"1\"><\/div>\n<\/div>\n<pre><span class=\"cm-def\">$ <\/span>.\/certbot-auto certonly <span class=\"cm-attribute\">-a<\/span> standalone <span class=\"cm-attribute\">-d<\/span> seeld.eu <span class=\"cm-attribute\">-d<\/span> www.seeld.eu<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"CodeMirror-gutters\">\n<div class=\"CodeMirror-gutter CodeMirror-linenumbers\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Keys are generated in\u00a0<strong>\/etc\/letsencrypt\/live\/seeld.eu<\/strong>.<br \/>\n<em><strong><br \/>\nRemark:\u00a0<\/strong><\/em>&#8216;certonly&#8217; &#8211; means that this command does not come with any special plugin like Apache or Nginx. &#8216;standalone&#8217; &#8211; \u00a0means that Let&#8217;s encrypt will automatically create a simple web server on port 80 to prove you control the domain.<\/li>\n<\/ol>\n<h2>How to Generate PKCS12 Files From PEM Files<\/h2>\n<p>Certificates and private keys are generated in 2 steps for free which shows the simplicity of Let&#8217;s Encrypt. All of these generated materials are with\u00a0PEM\u00a0extension which is not supported in Spring Boot.\u00a0Spring-Boot does not support PEM files generated by Let\u2019s Encrypt. Spring Boot supports\u00a0PKCS12\u00a0extension. Using OpenSSL, we convert our certificate and private key to PKCS12.<\/p>\n<p>To convert the PEM files to PKCS12 version:<\/p>\n<ol>\n<li>Go to \/etc\/letsencrypt\/live\/seeld.eu<\/li>\n<li>We convert the keys to PKCS12 using OpenSSL in the terminal as follows.\n<div class=\"CodeMirror cm-s-default\">\n<div class=\"CodeMirror-scroll\">\n<div class=\"CodeMirror-sizer\">\n<div class=\"CodeMirror-lines\">\n<div class=\"CodeMirror-code\">\n<div>\n<div class=\"CodeMirror-gutter-wrapper\">\n<div class=\"CodeMirror-linenumber CodeMirror-gutter-elt\" data-line-number=\"1\"><\/div>\n<\/div>\n<pre><span class=\"cm-variable\">$<\/span> <span class=\"cm-variable\">openssl<\/span> <span class=\"cm-variable\">pkcs12<\/span> <span class=\"cm-operator\">-<\/span><span class=\"cm-variable\">export<\/span> <span class=\"cm-operator\">-<\/span><span class=\"cm-variable\">in<\/span> <span class=\"cm-variable\">fullchain<\/span>.<span class=\"cm-variable\">pem <\/span><span class=\"cm-operator\">-<\/span><span class=\"cm-variable\">inkey<\/span> <span class=\"cm-variable\">privkey<\/span>.<span class=\"cm-variable\">pem -<\/span><span class=\"cm-variable\">out<\/span> <span class=\"cm-variable\">keystore<\/span>.<span class=\"cm-variable\">p12<\/span> <span class=\"cm-operator\">-<\/span><span class=\"cm-variable\">name<\/span> <span class=\"cm-variable\">tomcat -<\/span><span class=\"cm-variable\">CAfile<\/span> <span class=\"cm-variable\">chain<\/span>.<span class=\"cm-variable\">pem <\/span><span class=\"cm-operator\">-<\/span><span class=\"cm-variable\">caname<\/span> <span class=\"cm-variable\">root<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"CodeMirror-gutters\">\n<div class=\"CodeMirror-gutter CodeMirror-linenumbers\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<\/ol>\n<p>The file &#8216;keystore.p12&#8217; with PKCS12 is now generated in &#8216;\/etc\/letsencrypt\/live\/seeld.eu&#8217;.<\/p>\n<h2>Configuration of Your Spring Boot Application<\/h2>\n<p>Now we want to configure our Spring Boot application to benefit from the certificate and the private key; and eventually have the HTTPS thingy ready.\u00a0At this moment, we already generated our certificate and private key. Then we converted the keys to PKCS12 extension which is ready to be used for a Spring application.<\/p>\n<ol>\n<li>Open your &#8216;application.properties&#8217;<\/li>\n<li>Put this configuration there.\n<div class=\"CodeMirror cm-s-default\">\n<div class=\"CodeMirror-scroll\">\n<div class=\"CodeMirror-sizer\">\n<div>\n<div class=\"CodeMirror-lines\">\n<div>\n<div class=\"CodeMirror-code\">\n<div>\n<div class=\"CodeMirror-gutter-wrapper\">\n<div class=\"CodeMirror-linenumber CodeMirror-gutter-elt\" data-line-number=\"1\"><\/div>\n<\/div>\n<pre><span class=\"cm-def\">s<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">v<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">t<\/span>: <span class=\"cm-quote\">8<\/span><span class=\"cm-quote\">4<\/span><span class=\"cm-quote\">4<\/span><span class=\"cm-quote\">3<\/span><\/pre>\n<\/div>\n<div>\n<pre><span class=\"cm-def\">s<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">c<\/span><span class=\"cm-def\">u<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">i<\/span><span class=\"cm-def\">t<\/span><span class=\"cm-def\">y<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">q<\/span><span class=\"cm-def\">u<\/span><span class=\"cm-def\">i<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">-<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">l<\/span>=<span class=\"cm-quote\">t<\/span><span class=\"cm-quote\">r<\/span><span class=\"cm-quote\">u<\/span><span class=\"cm-quote\">e<\/span><\/pre>\n<\/div>\n<div>\n<pre><span class=\"cm-def\">s<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">v<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">l<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">k<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">y<\/span><span class=\"cm-def\">-<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">t<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">e<\/span>:<span class=\"cm-quote\">\/<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">t<\/span><span class=\"cm-quote\">c<\/span><span class=\"cm-quote\">\/<\/span><span class=\"cm-quote\">l<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">t<\/span><span class=\"cm-quote\">s<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">n<\/span><span class=\"cm-quote\">c<\/span><span class=\"cm-quote\">r<\/span><span class=\"cm-quote\">y<\/span><span class=\"cm-quote\">p<\/span><span class=\"cm-quote\">t<\/span><span class=\"cm-quote\">\/<\/span><span class=\"cm-quote\">l<\/span><span class=\"cm-quote\">i<\/span><span class=\"cm-quote\">v<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">\/<\/span><span class=\"cm-quote\">s<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">l<\/span><span class=\"cm-quote\">d<\/span><span class=\"cm-quote\">.<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">u<\/span><span class=\"cm-quote\">\/<\/span><span class=\"cm-quote\">k<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">y<\/span><span class=\"cm-quote\">s<\/span><span class=\"cm-quote\">t<\/span><span class=\"cm-quote\">o<\/span><span class=\"cm-quote\">r<\/span><span class=\"cm-quote\">e<\/span><span class=\"cm-quote\">.<\/span><span class=\"cm-quote\">p<\/span><span class=\"cm-quote\">1<\/span><span class=\"cm-quote\">2<\/span><\/pre>\n<\/div>\n<div>\n<pre><span class=\"cm-def\">s<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">v<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">l<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">k<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">y<\/span><span class=\"cm-def\">-<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">t<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">-<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">a<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">w<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">d<\/span>: <span class=\"cm-quote\">&lt;<\/span><span class=\"cm-quote\">y<\/span><span class=\"cm-quote\">o<\/span><span class=\"cm-quote\">u<\/span><span class=\"cm-quote\">r<\/span><span class=\"cm-quote\">-<\/span><span class=\"cm-quote\">p<\/span><span class=\"cm-quote\">a<\/span><span class=\"cm-quote\">s<\/span><span class=\"cm-quote\">s<\/span><span class=\"cm-quote\">w<\/span><span class=\"cm-quote\">o<\/span><span class=\"cm-quote\">r<\/span><span class=\"cm-quote\">d<\/span><span class=\"cm-quote\">&gt;<\/span><\/pre>\n<\/div>\n<div>\n<pre><span class=\"cm-def\">s<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">v<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">l<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">k<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">y<\/span><span class=\"cm-def\">S<\/span><span class=\"cm-def\">t<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">T<\/span><span class=\"cm-def\">y<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">e<\/span>: <span class=\"cm-quote\">P<\/span><span class=\"cm-quote\">K<\/span><span class=\"cm-quote\">C<\/span><span class=\"cm-quote\">S<\/span><span class=\"cm-quote\">1<\/span><span class=\"cm-quote\">2<\/span><\/pre>\n<\/div>\n<div>\n<pre><span class=\"cm-def\">s<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">v<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">l<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">k<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">y<\/span><span class=\"cm-def\">A<\/span><span class=\"cm-def\">l<\/span><span class=\"cm-def\">i<\/span><span class=\"cm-def\">a<\/span><span class=\"cm-def\">s<\/span>: <span class=\"cm-quote\">t<\/span><span class=\"cm-quote\">o<\/span><span class=\"cm-quote\">m<\/span><span class=\"cm-quote\">c<\/span><span class=\"cm-quote\">a<\/span><span class=\"cm-quote\">t<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"CodeMirror-gutters\">\n<div class=\"CodeMirror-gutter CodeMirror-linenumbers\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><em><strong>Remark<\/strong><\/em><span class=\"crayon-e\">&#8216;require<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">ssl&#8217; &#8211; means that your server only processes HTTPS-protected requests.<\/span><\/li>\n<\/ol>\n<p>If you visit\u00a0<a href=\"https:\/\/seeld.eu:8443\/\" rel=\"nofollow\">https:\/\/seeld.eu:8443<\/a>, you can see that HTTPS is successfully\u00a0configured and most importantly working. For the sake of our project, we did some additional steps to have HTTPS working with port 80, you can browse it with the\u00a0<a href=\"https:\/\/seeld.eu:8443\/\" rel=\"nofollow\">https:\/\/seeld.eu<\/a>\u00a0URL.<\/p>\n<p><a href=\"https:\/\/seeld.eu\/\" rel=\"nofollow\" data-fr-link=\"true\"><img decoding=\"async\" class=\"fr-fin fr-dib\" title=\"Seeld secured by Lets Encrypt\" src=\"https:\/\/dzone.com\/storage\/temp\/2794832-screen-shot-2016-08-14-at-133511.png\" alt=\"Seeld secured by Lets Encrypt\" width=\"565\" \/><\/a><\/p>\n<h2>Renewal Process<\/h2>\n<p><a href=\"https:\/\/letsencrypt.org\/\" rel=\"nofollow\">Let&#8217;s Encrypt<\/a>\u00a0certificates are only valid for\u00a090 days. Some may say 3 months is too short comparing to validity period of certificates offered by other providers. They have\u00a0two motivations\u00a0for this strict decision: (1) limiting damage from key compromise or mis-issuance; (2) encouraging automation. So let&#8217;s get started!<\/p>\n<ol>\n<li>Open your Let&#8217;s Encrypt client directory, I mean the\u00a0certbot.\u00a0<strong>Remarks:\u00a0<\/strong>On the same machine that certificates and keys are located. Please read all of the remarks from sections, such as having python installed, having port 80 open, etc.<\/li>\n<li>Run the renew command as follows.\n<div class=\"CodeMirror cm-s-default\">\n<div class=\"CodeMirror-scroll\">\n<div class=\"CodeMirror-sizer\">\n<div>\n<div class=\"CodeMirror-lines\">\n<div>\n<div class=\"CodeMirror-code\">\n<div>\n<div class=\"CodeMirror-gutter-wrapper\">\n<div class=\"CodeMirror-linenumber CodeMirror-gutter-elt\" data-line-number=\"1\"><\/div>\n<\/div>\n<pre><span class=\"cm-def\">$ sudo<\/span> .\/certbot-auto renew<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"CodeMirror-gutters\">\n<div class=\"CodeMirror-gutter CodeMirror-linenumbers\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>This command checks the expiry date of certificates located in this machine (managed by Let&#8217;s Encrypt), and renew the ones that are either expired or about to expire.<\/li>\n<\/ol>\n<p><strong>We have new certificates, as simple as that!<\/strong><\/p>\n<p>As discussed in the section:\u00a0Spring-Boot does not support PEM files generated by Let\u2019s Encrypt. Spring Boot supports\u00a0PKCS12\u00a0extension. Using OpenSSL, we convert our certificate and private key to PKCS12.<\/p>\n<h2>Preparation for Spring Boot<\/h2>\n<p><strong>Let&#8217;s create a PKCS#12 key store!<\/strong><\/p>\n<ol>\n<li>Go to \/etc\/letsencrypt\/live\/seeld.eu<\/li>\n<li>We convert the keys to PKCS12 using OpenSSL in the terminal as follows.\n<div class=\"CodeMirror cm-s-default\">\n<div class=\"CodeMirror-scroll\">\n<div class=\"CodeMirror-sizer\">\n<div class=\"CodeMirror-lines\">\n<div class=\"CodeMirror-code\">\n<div>\n<div class=\"CodeMirror-gutter-wrapper\">\n<div class=\"CodeMirror-linenumber CodeMirror-gutter-elt\" data-line-number=\"1\"><\/div>\n<\/div>\n<pre><span class=\"cm-def\">$<\/span> <span class=\"cm-def\">o<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">n<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">l<\/span> <span class=\"cm-def\">p<\/span><span class=\"cm-def\">k<\/span><span class=\"cm-def\">c<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">1<\/span><span class=\"cm-def\">2<\/span> <span class=\"cm-def\">-<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">x<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">t<\/span> <span class=\"cm-def\">-<\/span><span class=\"cm-def\">i<\/span><span class=\"cm-def\">n<\/span> <span class=\"cm-def\">f<\/span><span class=\"cm-def\">u<\/span><span class=\"cm-def\">l<\/span><span class=\"cm-def\">l<\/span><span class=\"cm-def\">c<\/span><span class=\"cm-def\">h<\/span><span class=\"cm-def\">a<\/span><span class=\"cm-def\">i<\/span><span class=\"cm-def\">n<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">m <\/span>-<span class=\"cm-def\">i<\/span><span class=\"cm-def\">n<\/span><span class=\"cm-def\">k<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">y<\/span> <span class=\"cm-def\">p<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">i<\/span><span class=\"cm-def\">v<\/span><span class=\"cm-def\">k<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">y<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">m <\/span><span class=\"cm-def\">-<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">u<\/span><span class=\"cm-def\">t<\/span> <span class=\"cm-def\">k<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">y<\/span><span class=\"cm-def\">s<\/span><span class=\"cm-def\">t<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">r<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">1<\/span><span class=\"cm-def\">2 <\/span><span class=\"cm-def\">-<\/span><span class=\"cm-def\">n<\/span><span class=\"cm-def\">a<\/span><span class=\"cm-def\">m<\/span><span class=\"cm-def\">e<\/span> <span class=\"cm-def\">t<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">m<\/span><span class=\"cm-def\">c<\/span><span class=\"cm-def\">a<\/span><span class=\"cm-def\">t <\/span>-<span class=\"cm-def\">C<\/span><span class=\"cm-def\">A<\/span><span class=\"cm-def\">f<\/span><span class=\"cm-def\">i<\/span><span class=\"cm-def\">l<\/span><span class=\"cm-def\">e<\/span> <span class=\"cm-def\">c<\/span><span class=\"cm-def\">h<\/span><span class=\"cm-def\">a<\/span><span class=\"cm-def\">i<\/span><span class=\"cm-def\">n<\/span><span class=\"cm-def\">.<\/span><span class=\"cm-def\">p<\/span><span class=\"cm-def\">e<\/span><span class=\"cm-def\">m <\/span>-<span class=\"cm-def\">c<\/span><span class=\"cm-def\">a<\/span><span class=\"cm-def\">n<\/span><span class=\"cm-def\">a<\/span><span class=\"cm-def\">m<\/span><span class=\"cm-def\">e<\/span> <span class=\"cm-def\">r<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">o<\/span><span class=\"cm-def\">t<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"CodeMirror-gutters\">\n<div class=\"CodeMirror-gutter CodeMirror-linenumbers\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<\/ol>\n<p>The file \u2018<em>keystore.p12<\/em>\u2019 with PKCS12 is now generated in \u2018\/etc\/letsencrypt\/live\/seeld.eu\u2019.<\/p>\n<p><strong>But wait!<\/strong><\/p>\n<p>I assume the machine that you&#8217;re woking on is the one with running Spring Boot. It means that we&#8217;re not done yet! The previous \u2018<em>keystore.p12<\/em>\u2019 is still in the memory, meaning that you need to\u00a0<strong>restart your application!\u00a0<\/strong><\/p>\n<p>It&#8217;s not always viable to simply restart a running application. There might be other ways to update it without restarting but it&#8217;s not in the scope of this post.<\/p>\n<h2>The Take-Home Message<\/h2>\n<p>In this post, we saw how to\u00a0<em>issue<\/em>,\u00a0<em>renew<\/em>\u00a0a Let&#8217;s Encrypt certificate, and most importantly, integrate it with\u00a0<em>Spring Boot<\/em>. If you really don&#8217;t unnecessarily play with configurations, it takes less than 5 minutes to have all things ready.<\/p>\n<p>The main takeaway message for me is that Let&#8217;s Encrypt makes (re-)issuing certificates incredibly faster, easier, and cheaper for everyone, no matter how many services you manage! You should start having HTTPS as soon as possible.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we want to know how we can (1) generate a valid certificate for free; (2) configure a Spring Boot app with it; and lastly (3) how to renew it when it expires. In my previous\u00a0blog post, we became familiar with configuration of an\u00a0Spring Boot Application\u00a0with a self-signed certificate. Self-signed certificates are good [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[730,1,830,725,42,51,495,68,271],"tags":[385,1172,1139,1232,1231],"class_list":["post-4558","post","type-post","status-publish","format-standard","hentry","category-clusterweb","category-viazap","category-debian","category-hospedagem","category-leitura-recomendada","category-linux-linuxrs","category-profissional-de-ti","category-redes-2","category-seguranca-2","tag-boot","tag-by","tag-lets-encrypt","tag-secured","tag-spring"],"_links":{"self":[{"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/posts\/4558","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4558"}],"version-history":[{"count":2,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/posts\/4558\/revisions"}],"predecessor-version":[{"id":4560,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/posts\/4558\/revisions\/4560"}],"wp:attachment":[{"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4558"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4558"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4558"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}