TLS/SSL certificates for developers
Dominik Rüttiger
Source: Photo by Global Residence Index on Unsplash
TLS/SSL certificates are the fundamental source of trust on the web. Everyone uses them every day, most without even knowing they exist. With modern zero trust architecture, developers have to deal with them even more.
I feel like many developers only learn the very basics to get along, which can lead to dangerous mistakes. Cryptographic Failures is #2 on the OWASP Top 10 for a reason.
Developers do not have to be experts on TLS/SSL certificates, but know how to handle them safely. Let’s go!
How can I trust someone on the web?
We visit a ridiculous number of websites every day, and we want to be sure that the people and companies behind them are who they say they are.
In real life, we can ask strangers to show us their passports. We have learned to judge the validity of a passport by checking features such as watermarks that presumably could only be produced by a government’s passport office. So as long as we trust the passport office, we can verify the identity.
On the web, certificates are the equivalent of passports. Every subject can get
a digital certificate from a certificate authority (CA
), which takes the role
of the passport office. There is a list of trusted CAs built into our browsers
and operating systems by their developers, that everyone is expected to trust.
Show me your passport!
Let’s check out the certificate of this blog. We are using commands provided by OpenSSL:
The hostname and DNS name can be set independently, which is handy for debugging
locally on a webserver (-connect localhost:443
).
The format is X.509 and includes:
- the authority that issued the certificate
- the validity time frame
- the domain names that the certificate is valid for
Usually, this certificate is Base64 encoded and looks like this:
Common filename extensions are .pem
, .cer
and .crt
.
Verify a passport
Let’s find out if we are dealing with a valid certificate:
If we see Verification: OK
and Verified peername: www.drsys.de
, we are good.
You could also set -connect localhost:443
for debugging locally on a
webserver. See the official docs for
more verification options.
Behind the scenes
The fascinating part is, that your browser is actually able to verify the certificates locally. This is possible using public-key cryptography with a digital signature.
First, let’s see how a certificate is requested from a certificate authority (
CA
):
- Create a key pair with a private and public key
- Send the public key together with a domain name to the CA
- this is called a Certificate Signing Request (
CSR
)- The CA verifies your identity (e.g. that you control the DNS entries)
- The CA creates a certificate which includes the information from the CSR and additional information like validity
- The CA signs it (calculate a hash, encrypt it with it’s private key and add it to the certificate)
- encrypting with the private key is specific for RSA and can be different for other algorithms
The Verification of the certificate then goes like:
- Check the validity and domain name
- Check if we trust the issuer
- Is the public key included in our local authorities list?
- Hash the certificate, decrypt the signature with the CA’s public key and compare the two
These steps usually have to be repeated multiple times, because it is common to have hierarchies of CAs:
We will do all these steps ourselves in the bonus section.
Get your own passport
Traditionally you would buy a TLS/SSL certificate from a company like DigiCert. But since 2015, the non-profit organisation Let’s Encrypt issues certificates for free through an easy, fully automated process. Some webservers/reverse proxys like Caddy and Traefik even obtain and renew certificates automatically.
Another option is to create your own certificate authority and make your users’ browsers trust it. This is common for internal applications in enterprises.
Use your passport
Getting a TLS/SSL certificate from Let’s Encrypt is very easy if you have a server with a public ip address.
-
Set DNS A/AAAA records to point to the server
-
Create a Caddy configuration file:
-
Create a Docker Compose file:
-
Start Caddy:
-
Open your domain (e.g. https://demo.example.com) in the browser and check the certificate
For more use cases, like using Caddy as a reverse proxy, see the official Caddy docs.
Bonus: Make your own passport
It’s totally possible to create your own CA, sign certificates and use them with your server. We will also see how we can trust our CA and validate the result.
-
Run these commands:
-
Check the files:
-
Create a Caddy configuration file:
-
Create a Docker Compose file:
-
Start Caddy:
-
Verify the served certificate by explicitly setting our root CA certificate as trusted:
FAQ
What do TLS and SSL stand for?
Transport Layer Security and Secure
Sockets Layer.
How is SSL related to TLS?
The now-deprecated SSL specification is the
predecessor of the TLS protocol. The term SSL is still widely used though, but
usually just refers to TLS.
How can I import TLS/SSL certificates to my operating system?
For
Debian/Ubuntu Linux, save the files in the /usr/local/share/ca-certificates/
folder with suffix .crt
and import them with
/usr/sbin/update-ca-certificates
.
What happens if someone gets control of one of the CAs built into our browsers
and operating systems?
This would be catastrophic because it would
allow them to fake any identity on the web.
How does Let’s Encrypt’s CA hierarchy look like?
Let’s Encrypt has two
root CAs ISRG Root X1
and ISRG Root X2
and four intermediate CAs. For more
details see the
official “Chains of Trust” documentation.
The root certificates are already
available on our systems.
On Linux, you can analyse them with:
How can I see/verify SMTP server certificates?
The default port for
secure connection is 587. If the SMTP server is still using STARTTLS, use the
-starttls smtp
option.
Tags
#bash #dev #devops #linux #security