Setup up HTTPS for your e-commerce site with Let’s Encrypt and Google App Engine.
HTTPS is an important part of keeping your customer’s information secure on the web—here’s a quick tutorial on how to set up HTTPS on your App Engine website to use our e-commerce APIs.
Security on the web is hugely important, especially when someone is trusting you with their payment card information. Even though Square handles the complex parts of PCI compliance for you, we do require your e-commerce forms to be served from an HTTPS domain. There is plenty of literature online about why you should be using HTTPS for your websites (including this great post by Google), so let’s focus on how to actually get a certificate for your website. I’ll demonstrate with my personal website.
No HTTPS here 😔 …yet
Step 0: Getting Ready.
This walkthrough will assume you have the following:
- A domain name for your e-commerce site
- A web server or hosting service where you host your website
- OpenSSL installed on your computer
If you use a different web host, it’s a good idea to see if your web hosting supports Let’s Encrypt directly. If so, it should be fairly easy to enable it for your website. You can see a list of supported web hosting providers here: https://community.letsencrypt.org/t/web-hosting-who-support-lets-encrypt/6920.
There are also a wide variety of other Certificate Authorities that can offer you similar or more advanced services for a price.
Step 1: Generate your private key and CSR (Certificate Signing Request)
First, use OpenSSL to generate a new private key and Certificate Signing Request.
$ openssl req -newkey rsa:2048 -keyout tristansokol.com.private.key -nodes -sha512 -subj "/CN=tristansokol.com" -reqexts SAN -out tristansokol.com.csr.der -outform der -config <(cat /System/Library/OpenSSL/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:tristansokol.com,DNS:www.tristansokol.com"))
The command is pretty long, so let’s break it down:
openssl reqis the command for the certificate request generating utility.
-newkeyflag tells openssl that we want to create a new request, and a new private key. It takes an argument about what kind of algorithm to use and how large of a key to generate. In this case, I am specifying an RSA key of 2048 bits.
-keyoutspecifies where to write the new private key to. Keep in mind, I recommend you change the file name to match your website (and not mine).
-nodesisn’t the word “nodes”. It specifies “no DES” and indicates that I don’t want to encrypt the new private key.
-sha512is my chosen message digest to sign our request.
-subjsets the subject names for the new request. In this case I want to sign a domain name, so I’ll use the common name (CN) of my website, hence the
-reqextsis a flag for using certificate request extensions. In this case I’ll use Subject Alternative Names (SAN) for the naked domain, and www. version of my site.
-outspecifies the filename to write the certificate request to.
-outformlets you choose between
-configis used to specify our configuration file. To make this more concise, I’ve inlined the creation of this file with options about the alternative names that our website goes by. Again, be sure to change these to your own domain.
You can read more about the options for
openssl reqon the offical man page: https://www.openssl.org/docs/man1.1.0/apps/req.html
You should now have two new files in your working directory (and again, yours will have your domain name instead of mine):
Step 2. Run the certbot command
Certbot (formerly the Let’s Encrypt Client) is a tool to obtain certificates from Let’s Encrypt. I’m on a Mac, so I’ll be using
brew install certbot for installation. https://certbot.eff.org should have instructions for your system.
sudo certbot certonly -a manual --server[ https://acme-v01.api.letsencrypt.org/directory](https://acme-v01.api.letsencrypt.org/directory) --csr tristansokol.com.csr.der
-awith no argument specifies that we will not be using an authenticator plugin.
manualindicates that I am generating my certificate on a machine other than my webserver, and I’ll do the domain validation myself.
--serverspecifies the ACME Directory Resource.
--csrspecifies the Certificate Signing Request (CSR) that should be used. In this case I’ll use the one I created in Step 1.
Certbot will now take you through a guided walkthrough to set up your certificate. Eventually, I hit the following step:
Make sure your web server displays the following content at[ http://tristansokol.com/.well-known/acme-challenge/xxx](http://tristansokol.com/.well-known/acme-challenge/xxx) before continuing:
This is a challenge (the url) and response pair that will be used to prove that you own this domain. That means I’ll need to add an additional request handler to this site to respond to these challenges. Luckily, it is fairly simple with App Engine.
Step 3: Rise to the challenge
In order to serve the challenge response from my website at the challenge URLs, I need to do a couple things. First, I created a new text file with the the response I was supposed to serve, and saved it as ACME-response.txt. Then I updated my app.yaml to serve that page at the specified directory.
#app.yaml #SSL challenge and response - url: /.well-known/acme-challenge/xxx static_files: ACME-response.txt upload: ACME-response.txt
This tells App Engine to respond to requests at
/.well-known/acme-challenge/x(my challenge URL) with the content of my response. Then I used the local development server with
dev_appserver.py app.yaml to double-check that everything was working before deploying with
gcloud app deploy.
After repeating those steps for the www. version of my domain, I can continue.
Step 2. (cont) Finishing up with Certbot
With my challenge responses good to go, Certbot generated a certifcate and two cert chains.
Step 4: Adding my certifcate to App Engine
Now that I’ve verified and generated everything, I can go to the certificate management page of my app engine project and hit upload new certificate. For the PEM encoded X.509 public key certificate I’ll upload my
0001_chain.pem file that I just generated. For the Unencrypted PEM encoded RSA private key I uploaded my
tristansokol.com.private.key file from Step 1.
Then I enabled it for both my naked and www. domains. I also edited my app.yaml file to include
secure always for the request handlers of my pages. Now when I navigate to my personal website, users will be automatically redirected to the https version, inspiring trust for visitors to my site, and keeping my e-commerce customers safe.
To learn more about Square’s e-commerce platform, check out square.com/developer.