Setting up HTTPS for your e-commerce website 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.
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
I’ll enable HTTPS for my personal website: www.tristansokol.com. I use Google App Engine to serve my site, and will be using Let’s Encrypt—a free, automated, and open Certificate Authority.
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 req
is the command for the certificate request generating utility.- The
-newkey
flag 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. -keyout
specifies 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).-nodes
isn’t the word “nodes”. It specifies “no DES” and indicates that I don’t want to encrypt the new private key.-sha512
is my chosen message digest to sign our request.-subj
sets 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“/CN=tristansokol.com”
.-reqexts
is 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.-out
specifies the filename to write the certificate request to.-outform
lets you choose betweender
orpem
output formats.-config
is 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 req
on 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):
tristansokol.com.csr.der
tristansokol.com.private.key
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.
Next run:
sudo certbot certonly -a manual --server https://acme-v01.api.letsencrypt.org/directory --csr tristansokol.com.csr.der
-a
with no argument specifies that we will not be using an authenticator plugin.manual
indicates that I am generating my certificate on a machine other than my webserver, and I’ll do the domain validation myself.--server
specifies the ACME Directory Resource.- And
--csr
specifies 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 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.
0000_cert.pem
0000_chain.pem
0001_chain.pem
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.