Creating SSL Certs For Amazon API Gateway Using ZeroSSL And Let's Encrypt
Let’s Encrypt is a free Certificate Authority for TLS, which we believe is a crucial advance for the Open Web. ZeroSSL takes the great work Let’s Encrypt is doing one step farther, by making it easier to create LE certs. So there’s more reason than ever to protect your Web sites or apps with TLS. In this post, we’re going to walk you through using ZeroSSL to generate a cert for Amazon’s API Gateway service. And you won’t need to install a thing!
SSL/TLS encrypts HTTP traffic between a Web client and server. The server has to prove to the client that it isn’t an imposter, intercepting the client’s requests while pretending to be the server. Informally, this dialog goes something like this:
Server: Here’s a document signed by me, swearing that I own the domain associated with this server.
Client: Sorry, but I don’t know you. Can anyone vouch for you?
Server: Yup! The folks at Let’s Encrypt have verified that I own this domain. They’ve signed that document, too.
Client: Oh, I know those guys. This signature looks legit. Alright, I believe you. Let’s pick a key to encrypt the rest of this discussion.
Of course, saying “the document provided to the client that proves domain ownership” is tedious. So we have a nice shorthand:
A Certificate is a signed assertion of ownership of a given domain. It’s a way to say, hey, I’m really who I say I am.
To use a Certificate, you need a private key, which allows you to sign your assertion that you own a domain. It’s like having a signature card on file at your bank. So you can say hey, I’m really who I say I am, and then sign the statement with your unique signature.
A Certificate Authority is a trusted entity that issues Certificates. In this case, the CA is Let’s Encrypt. So when you say, hey, I’m really who I say I am, the CA is vouching for you.
A Certificate Signing Request (CSR) is a request to a CA for a certificate for a given domain, digitally signed by the applicant. You’re asking the CA to vouch for you.
Generating The CSR
With that out of the way, we’re ready to create our cert! Go to the ZeroSSL site, and click on Certificates And Tools option in the menu on the left-hand side. Scroll down a bit to the section entitled CSR Generator. Click the Start button.
(The wizard can optionally generate a CSR for you, but for a 4096-bit key. We need a 2048-bit key because that’s what the AWS API Gateway uses. Hopefully, they’ll support 4096-bit keys soon.)
Enter the domains you want the SSL cert for. In our case, we wanted a dedicated subdomain for our API, so we entered
Select whether you want a 4096-bit or 2048-bit key. Again, in our case, we need a 2048-bit key, but normally you’d want a 4096-bit key (which is why it’s the default).
Click the Generate button.
You’ll get a private key for use with the domain on the left
and the corresponding CSR on the right.
Click the download button on both of these,
which will save files named
Applying For A Cert
Go back to Certificates And Tools and this go to the section entitled FREE SSL Certificate Wizard and click Start again.
Enter your email and paste the contents of the
csr.txtfile into the box on the righthand side.
Select either HTTP or DNS verification. This is how you tell LE that you really do own the domain in question. If you can add DNS records for the domain, I think DNS verification is the easiest. With either approach, the idea is to associate an unguessable token, generated by LE, with the domain.
Save Your LE Account Key
ZeroSSL will helpfully create an LE account key for you.
The key is generated in the browser.
The ZeroSSL servers never have your private keys.
Use the download button to save this
into a file called
You can use this key in the future instead
of generating a new one each time
you want to use LE or ZeroSSL.
(You can also use an existing key if you have one.)
Click Next again to submit the request.
Now you have to prove you own the domain.
For domain verification,
you associate a
TXT record with the domain.
TXT record will contain an unguessable token.
LE can check this text record and see that,
for all intents and purposes, you control that domain.
How to do this depends on your DNS provider.
You can also choose to make the token available via a file on your site. Again, the exact steps for doing this depend on how you’re hosting your site.
Once you’ve updated your Web site or DNS record (depending on which option you pick) you can move on to the next step. If you use DNS verification, remember to allow some time for the DNS update to propagate.
Creating The Cert
The final step in the wizard allows you to download
your certification — victory at last!
The first field contains your private key.
The second field contains the certificate.
The certificate contains both the domain and LE certs.
Both are necessary, since they tell Web clients
not only who you are, but who’s vouching for you.
Use the download button to save the private key
and the cert in files —
ZeroSSL places both certs into one file
because most modern Web servers accept them in that format.
But the AWS API Gateway wants them separately.
So let’s split our
domain-crt.txt file into two files.
They’re in PEM format which is delimited with:
Cut and paste the second certificate into a file named
This last step leaves us with:
account-key.txt: Your LE account key.
domain-key.txt: The private key for the domain.
csr.txt: The CSR for the domain.
domain-crt.txt: The domain certificate.
issuer-crt.txt: The LE certificate.
Save LE account key and the CSR so you can renew the domain later. We’ll use the domain key and cert and the issuer cert with the AWS API Gateway.
Using Our Cert
For the AWS API Gateway, click the Create Custom Domain button.
Enter the domain name into the Domain name field.
Enter a logical name into the Certificate name field. Ex:
Paste the domain cert (
domain-crt.txt) into the Certificate body field.
Paste the domain key (
domain-key.txt) into the Certificate private key field.
Paste the issuer cert (
issuer-crt.txt) into the Certificate chain field.
Click the Save button.
Once completed, AWS will create a CloudFront distribution domain for your API, to which you can point the domain!
You can also do this via the AWS CLI, like this:
aws apigateway create-domain-name \ --region "<your-region>" \ --domain-name "<domain name>" \ --certificate-name "<logical name>" \ --certificate-body "file://domain-crt.txt" \ --certificate-private-key "file://domain-key.txt" \ --certificate-chain "file://issuer-crt.txt" \ --output text \ --query distributionDomainName
which will return the CloudFront distribution domain.
And that’s it! The hardest part of the entire process is becoming familiar with all the various keys and certs. But we didn’t need to install a thing (unless you want to use the AWS command-line tool, but that’s optional). And it’s all free.
Special thanks to Alexander Yezhov the author of ZeroSSL, who was extremely helpful and patient in answering my questions. Alexander is also the author of The Internet Privacy Test. And, of course, thank you to all the folks behind Let’s Encrypt for making TLS certificates creation just another part of the Open Web.