skip to content

Search

Syspirit
EN

#SSL/TLS Certificates: Types, Chains and Installation

14 min read Karl Certa
SSL/TLS Certificates Types Cover
AI-generated image

SSL/TLS certificates used to give me a hard time. Every time I had to install one, it was the same story: what’s in this file? Is it the right format? And how do I install it on this server? In short, I was lost.

This article is the one I wish I had back then: understanding what a certificate is, the different types that exist, how the chain of trust works, and most importantly how to handle and install these files on Windows and Linux.

The Fundamentals


What is SSL/TLS?

SSL (Secure Sockets Layer) and TLS (Transport Layer Security) are the same thing… or almost. SSL is the historical name of the protocol created by Netscape in the 90s to secure Internet communications. TLS is its successor, more modern and more secure.

In practice:

  • SSL 1.0, 2.0, 3.0 → obsolete and vulnerable, should no longer be used
  • TLS 1.0, 1.1 → deprecated
  • TLS 1.2, 1.3 → current and recommended versions

Today, when people talk about “SSL certificates”, they’re actually referring to TLS. The term SSL stuck around out of habit, but technically it’s TLS running behind the scenes.

The default port for HTTPS is 443 (versus 80 for HTTP). This is the port where the server listens for secure connections.

What is an SSL/TLS Certificate?

When you connect to a website over HTTPS, several things happen:

  1. The browser contacts the server
  2. The server sends its certificate
  3. The browser verifies that this certificate is valid and trustworthy
  4. If everything is OK, an encrypted connection is established

The certificate is the central piece that allows proving the server’s identity and establishing a secure connection. Without it, no HTTPS.

Specifically, a certificate contains:

  • The domain name for which it’s valid (e.g., syspirit.fr)
  • A public key used to initiate encryption
  • The issuer’s identity (the certificate authority that signed it)
  • A validity period (start and expiration dates)
  • A digital signature that guarantees the certificate hasn’t been tampered with

It’s like a digital ID card: it says “I am indeed syspirit.fr” and a recognized authority (the CA) confirms it’s true.

Private Key vs Public Key

To understand certificates, you first need to understand the principle of asymmetric cryptography. Unlike traditional encryption where a single password is used to encrypt and decrypt, here we have two keys that work together:

  • The public key: as the name suggests, it’s public. You can distribute it to everyone. It’s included in the certificate.
  • The private key: it remains secret, only on the server. It must never be shared.

The principle is simple:

  • What is encrypted with the public key can only be decrypted with the private key
  • What is signed with the private key can be verified with the public key

This mechanism allows establishing a secure connection: the client uses the server’s public key (contained in the certificate) to initiate an encrypted exchange, and only the server that possesses the corresponding private key can decrypt and respond.

The Chain of Trust (PKI)

OK, we have a certificate with a public key. But how does the browser know it can trust it? Anyone can generate a certificate…

That’s where Certificate Authorities (CA) come in. A CA is a recognized organization (DigiCert, Let’s Encrypt, Sectigo…) that verifies the requester’s identity before signing their certificate. This signature is the guarantee that “yes, this certificate is legitimate”.

But root CAs are too precious to directly sign thousands of certificates. If a root is compromised, all trust collapses. So they delegate to intermediate CAs.

Here’s what a typical chain looks like:

Root CA
    └── Intermediate CA 1
            └── Intermediate CA 2
                    └── Server Certificate (your site)

Why multiple intermediates?

  • Security: if an intermediate is compromised, it can be revoked without touching the root
  • Organization: large CAs often have multiple intermediates for different purposes (DV, OV, EV, regions…)

The Trust Store

How does the browser know which CAs are trustworthy? It uses a trust store: a pre-installed list of trusted root certificates.

  • Windows: managed by Microsoft, accessible via certlm.msc
  • Linux: files in /etc/ssl/certs/ (Debian) or /etc/pki/ca-trust/ (RHEL)
  • Browsers: Firefox has its own trust store, Chrome/Edge use the system’s

These trust stores contain certificates from major public CAs (DigiCert, Let’s Encrypt, GlobalSign…). That’s why when you visit a site with a Let’s Encrypt certificate, it works right away: the CA is already recognized.

What About Enterprise Certificates?

In enterprise environments, it’s different. There’s often an internal CA (via Active Directory Certificate Services for example) that generates certificates for internal applications, servers, WiFi…

The problem: this internal CA is not in the default trust store. The browser doesn’t know it. Result → “Certificate not trusted” or “Connection not secure”.

The solution? Add the internal CA certificate to the machines’ trust store. In enterprise, this is usually done via GPO (Group Policy): the admin deploys the CA root certificate to all domain computers. Once done, all certificates signed by this CA will be automatically recognized as valid.

That’s why a certificate that works perfectly at the office can show an error on a personal PC: the company’s CA is not in its trust store.

Certificate Types


By Validation Level

TypeValidationDelayPriceUsage
DV (Domain Validation)Just the domainMinutesFree to ~$50/yearBlogs, personal sites, APIs
OV (Organization Validation)Domain + organization1-3 days$50-200/yearBusiness sites
EV (Extended Validation)Thorough verification1-2 weeks$200-500/yearE-commerce, banks

DV (Domain Validation): The CA simply verifies that you control the domain (via DNS or HTTP file). This is what Let’s Encrypt offers for free. Perfect for 90% of use cases.

OV (Organization Validation): The CA also verifies the legal existence of the organization. The company name appears in the certificate.

EV (Extended Validation): Thorough verification (legal documents, phone call…). Historically, this displayed a green bar in the browser, but this is no longer the case since 2019. Its usefulness is now debatable.

By Coverage

TypeExampleCovers
Single domainsyspirit.frA single FQDN
Wildcard*.syspirit.frAll direct subdomains
SAN / Multi-domainsyspirit.fr, karlcerta.frMultiple different domains

Wildcard: Convenient for covering all your subdomains with a single certificate. Note that *.syspirit.fr covers blog.syspirit.fr but not sub.blog.syspirit.fr (you would need *.blog.syspirit.fr).

SAN (Subject Alternative Name): Allows putting multiple completely different domains in a single certificate. Widely used in enterprise.

File Formats


This is where things often get confusing. Several formats exist, and file extensions aren’t always consistent…

Main Formats

PEM (Privacy Enhanced Mail)

PEM is an encoding format: the binary content of the certificate is converted to readable text (Base64). This allows opening a certificate with a simple text editor and seeing something like this:

-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiUMA0Gcg...
(Base64 content)
...Uv3nX8d2xPDz==
-----END CERTIFICATE-----

The confusing part: the file extension doesn’t necessarily indicate it’s PEM. A .crt, .cer, .pem or .key file can be in PEM format. What matters is what’s inside.

How to know if it’s PEM? If the file starts with -----BEGIN, it’s PEM. Otherwise, it’s probably binary (DER).

What you can find in a PEM file:

HeaderContent
-----BEGIN CERTIFICATE-----A certificate
-----BEGIN PRIVATE KEY-----A private key
-----BEGIN RSA PRIVATE KEY-----An RSA private key (old format)
-----BEGIN CERTIFICATE REQUEST-----A certificate request (CSR)

A single .pem file can contain multiple concatenated blocks. This is useful in two cases:

1. The certificate chain: when configuring a web server, you often need to provide the site certificate + intermediate certificates. Rather than 3 separate files, you put everything in one:

-----BEGIN CERTIFICATE-----
(site certificate)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(intermediate certificate 1)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(intermediate certificate 2)
-----END CERTIFICATE-----

This is what Let’s Encrypt calls fullchain.pem for example.

2. Certificate + private key: some software or appliances (HAProxy, some load balancers, legacy applications…) require a single file with everything in it:

-----BEGIN CERTIFICATE-----
(certificate)
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
(private key)
-----END PRIVATE KEY-----

This is convenient for these cases, but it’s less recommended security-wise — you generally prefer keeping the private key in a separate file with restrictive permissions.

Common extensions for PEM files:

  • .pem → generic extension, can contain anything
  • .crt / .cer → usually a certificate
  • .key → usually a private key

But again, the extension is just a convention. A .crt can very well be in DER format (binary) on some systems.

DER (Distinguished Encoding Rules)

Binary format, not readable with a text editor. If you open a DER file with an editor, you see incomprehensible characters.

It’s exactly the same content as a PEM file, but without Base64 encoding. DER is the “raw” format, PEM is the “readable” format.

When to use DER instead of PEM?

  • Some Java applications prefer DER
  • Historically more common on Windows (but PFX took over)
  • Sometimes required by network equipment or appliances

In practice, we mostly handle PEM on Linux and PFX on Windows. DER is rarer.

Extensions: .der, .cer

PFX / PKCS#12

This is the format used on Windows. A PFX file is a container that bundles everything you need:

  • The certificate
  • The private key
  • Intermediate certificates (optional)

Everything is protected by a password. This allows transporting a complete certificate in a single secure file.

Typical use cases:

  • Import a certificate into IIS
  • Install a certificate on a Windows server
  • Transfer a certificate from one machine to another
  • Backup a certificate with its private key

When you buy a certificate from a CA or export one from Linux, you often need to convert it to PFX before installing it on Windows. This is one of the most common conversions (we’ll see this in the OpenSSL section).

Extensions: .pfx, .p12 (they’re the same)

PKCS#7

Container for certificates without private key. Used to distribute a certificate chain only.

You sometimes encounter it when a CA sends the certificate + intermediates in a single file, but without the private key (which was generated on our side).

Extensions: .p7b, .p7c

File Summary

ExtensionFormatContentMain Usage
.keyPEMPrivate key onlyLinux, secure storage
.csrPEMCertificate requestGeneration with a CA
.crt / .cerPEM or DERCertificateUniversal
.pemPEMEverything (key, cert, chain)Linux
.pfx / .p12PKCS#12Certificate + key + chainWindows, IIS
.p7bPKCS#7Chain without keyChain distribution

How to Recognize a Format?

Not always obvious since extensions sometimes lie. Here’s how to verify:

# If it starts with "-----BEGIN", it's PEM
head -1 certificate.crt
 
# Verify a PEM file
openssl x509 -in certificate.crt -text -noout
 
# If error "unable to load certificate", try DER
openssl x509 -in certificate.cer -inform DER -text -noout
 
# Verify a PFX (asks for password)
openssl pkcs12 -in certificate.pfx -info -noout

Conversions with OpenSSL


OpenSSL is the go-to tool for handling certificates. Here are the most common conversions.

PEM ↔ DER

# PEM to DER
openssl x509 -in certificate.pem -outform DER -out certificate.der
 
# DER to PEM
openssl x509 -in certificate.der -inform DER -out certificate.pem

Create a PFX (for Windows)

This is THE most common conversion: bundle the certificate, private key and chain into a PFX file to import on Windows.

# Certificate + private key
openssl pkcs12 -export -out certificate.pfx \
    -inkey private-key.key \
    -in certificate.crt
 
# With intermediate chain
openssl pkcs12 -export -out certificate.pfx \
    -inkey private-key.key \
    -in certificate.crt \
    -certfile intermediate-chain.crt

You’ll be asked for a password to protect the PFX. Don’t lose it!

Extract from a PFX

Reverse operation: retrieve elements from a PFX (useful when migrating from Windows to Linux).

# Extract the certificate
openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.crt
 
# Extract the private key
openssl pkcs12 -in certificate.pfx -nocerts -nodes -out private-key.key
 
# Extract the intermediate chain
openssl pkcs12 -in certificate.pfx -cacerts -nokeys -out chain.crt

The -nodes option (no DES) avoids re-encrypting the private key with a password.

Generate a CSR (Certificate Request)

If you need to order a certificate from a CA:

# Generate private key + CSR
openssl req -new -newkey rsa:2048 -nodes \
    -keyout private-key.key \
    -out request.csr
 
# Generate CSR from existing key
openssl req -new -key private-key.key -out request.csr

Let’s Encrypt and ACME


Let’s Encrypt revolutionized the certificate world by offering free and automated DV certificates. Today, it’s the most used CA in the world.

The ACME Protocol

ACME (Automatic Certificate Management Environment) is the protocol that automates the entire process:

  1. Prove you control the domain
  2. Obtain the certificate
  3. Renew it automatically

Certbot: The Reference Tool

Certbot is the official ACME client from Let’s Encrypt.

Installation

Debian/Ubuntu:

sudo apt update
sudo apt install certbot
 
# For Nginx
sudo apt install python3-certbot-nginx
 
# For Apache
sudo apt install python3-certbot-apache

RHEL/CentOS/Rocky:

sudo dnf install epel-release
sudo dnf install certbot
 
# For Nginx
sudo dnf install python3-certbot-nginx
 
# For Apache
sudo dnf install python3-certbot-apache

The Challenges

To prove you control the domain, Let’s Encrypt offers two methods:

HTTP-01: Certbot places a file on your web server. Let’s Encrypt verifies it via http://yourdomain/.well-known/acme-challenge/xxx.

# With Nginx (configures automatically)
sudo certbot --nginx -d example.com
 
# With Apache
sudo certbot --apache -d example.com
 
# Standalone mode (temporarily stops web server)
sudo certbot certonly --standalone -d example.com

DNS-01: You create a TXT record in your DNS zone. Required for wildcards.

# Manual DNS challenge
sudo certbot certonly --manual --preferred-challenges dns -d "*.example.com"
 
# With a DNS plugin (Cloudflare example)
sudo certbot certonly --dns-cloudflare \
    --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
    -d "*.example.com"

Automatic Renewal

Let’s Encrypt certificates expire after 90 days. Certbot automatically configures a systemd timer or cron job for renewal.

# Check the timer
sudo systemctl status certbot.timer
 
# Test renewal (dry-run)
sudo certbot renew --dry-run
 
# Force renewal
sudo certbot renew --force-renewal

Where Are the Files?

After generation, certificates are located in /etc/letsencrypt/live/yourdomain/:

FileContent
privkey.pemPrivate key
cert.pemCertificate only
chain.pemIntermediate chain
fullchain.pemCertificate + chain (what you usually use)

Installation on Linux


Debian/Ubuntu

Standard Paths

PathUsage
/etc/ssl/certs/Public certificates
/etc/ssl/private/Private keys (restricted access)
/usr/local/share/ca-certificates/Custom CAs to add to trust store

Add a CA to the Trust Store

If you have an internal or self-signed CA:

# Copy the CA certificate (must be .crt, PEM format)
sudo cp my-ca.crt /usr/local/share/ca-certificates/
 
# Update the trust store
sudo update-ca-certificates

Nginx Configuration

server {
    listen 443 ssl;
    server_name example.com;
 
    ssl_certificate /etc/ssl/certs/example.com.crt;      # or fullchain.pem
    ssl_certificate_key /etc/ssl/private/example.com.key;
 
    # Intermediate certificates (if not in fullchain)
    # ssl_trusted_certificate /etc/ssl/certs/chain.crt;
 
    # Recommended SSL configurations
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
 
    # ...
}
# Test config
sudo nginx -t
 
# Reload
sudo systemctl reload nginx

Apache Configuration

<VirtualHost *:443>
    ServerName example.com
 
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/example.com.key
    SSLCertificateChainFile /etc/ssl/certs/chain.crt
 
    # ...
</VirtualHost>
# Enable SSL module
sudo a2enmod ssl
 
# Test and reload
sudo apachectl configtest
sudo systemctl reload apache2

RHEL/CentOS/Rocky

Standard Paths

PathUsage
/etc/pki/tls/certs/Certificates
/etc/pki/tls/private/Private keys
/etc/pki/ca-trust/source/anchors/Custom CAs

Add a CA to the Trust Store

# Copy the CA certificate
sudo cp my-ca.crt /etc/pki/ca-trust/source/anchors/
 
# Update the trust store
sudo update-ca-trust

Nginx/Apache Configuration

Same as Debian, only paths change (/etc/pki/tls/ instead of /etc/ssl/).

Permissions and Security

# Private key: read-only for root
sudo chmod 600 /etc/ssl/private/example.com.key
sudo chown root:root /etc/ssl/private/example.com.key
 
# Certificate: readable by all
sudo chmod 644 /etc/ssl/certs/example.com.crt

Installation on Windows


Via MMC (GUI)

Windows uses the Certificate Store to manage certificates. Two consoles exist:

  • certlm.msc: machine certificates (services, IIS…)
  • certmgr.msc: current user certificates

Import a PFX

  1. Open certlm.msc (Win + R, then certlm.msc)
  2. Navigate to PersonalCertificates
  3. Right-click → All TasksImport
  4. Select the .pfx file
  5. Enter the password
  6. Choose “Place all certificates in the following store” → Personal
  7. Finish

Add a CA to the Trust Store

To trust an internal CA:

  1. Open certlm.msc
  2. Navigate to Trusted Root Certification AuthoritiesCertificates
  3. Right-click → All TasksImport
  4. Select the CA certificate

Via PowerShell

# Import a PFX into machine store
$password = ConvertTo-SecureString -String "YourPassword" -Force -AsPlainText
Import-PfxCertificate -FilePath "C:\certs\certificate.pfx" `
    -CertStoreLocation Cert:\LocalMachine\My `
    -Password $password
 
# List certificates
Get-ChildItem Cert:\LocalMachine\My
 
# Export a certificate (without private key)
Export-Certificate -Cert Cert:\LocalMachine\My\THUMBPRINT `
    -FilePath "C:\certs\export.cer"

IIS (Internet Information Services)

Import the Certificate

  1. Open IIS Manager
  2. Select the server in the tree
  3. Double-click Server Certificates
  4. On the right, click Import
  5. Select the .pfx file and enter the password

Configure HTTPS Binding

  1. Select your site
  2. On the right, click Bindings
  3. Add → Type: https, Port: 443
  4. Select the certificate from the dropdown
  5. OK

AD CS (Active Directory Certificate Services)

For enterprise environments, Windows Server offers AD CS: a complete internal PKI to issue your own certificates.

This is a topic on its own, but in summary:

  • You create your own root CA
  • You deploy certificates via GPO
  • All domain computers automatically trust your CA

Useful for internal certificates, VPN, WiFi 802.1X, etc.

Conclusion


SSL/TLS certificates can seem complex at first, but once you understand the basic concepts — chain of trust, file formats, and conversion tools — it becomes much more manageable 😁.

Key points to remember:

  • The chain of trust: Root CA → Intermediate(s) → Server Certificate. Don’t forget the intermediates!
  • The formats: PEM (text, Linux) vs PFX (binary with key, Windows). OpenSSL converts everything.
  • Let’s Encrypt: free, automated, perfect for 90% of use cases
  • The private key is sacred: never share it, restrictive permissions

With these basics, you should be able to handle most situations. And if you’re still struggling, openssl s_client and SSL Labs are your best friends for debugging!

Useful links: