SSL/TLS Overview
SSL/TLS is a protocol for encrypting communication over the internet. SSL (Secure Sockets Layer) is the older name; its successor TLS (Transport Layer Security) is what is actually used today. By combining public-key cryptography with symmetric-key cryptography in a hybrid scheme, it protects against eavesdropping, tampering, and impersonation. The identity of a web server is guaranteed by a digital certificate issued by a Certificate Authority (CA). Browsers verify the legitimacy of a connection by following the certificate chain. On Linux, the openssl command is used to inspect certificates, generate CSRs, and create self-signed certificates.
Syntax
# -----------------------------------------------
# Main subcommands of the openssl command
# -----------------------------------------------
# openssl s_client -connect {hostname}:{port}
# → Establishes a TLS connection and retrieves the server's certificate information
# → Use the -showcerts option to display the full certificate chain
# Example: openssl s_client -connect wp-p.info:443
# openssl x509 -in {certificate file} -text -noout
# → Displays detailed information (issuer, expiration date, SANs, etc.) from a PEM certificate file
# Example: openssl x509 -in /etc/ssl/certs/wp-p.crt -text -noout
# openssl genrsa -out {private key file} {key length}
# → Generates an RSA private key
# → Minimum key length is 2048 bits; 4096 bits is recommended
# Example: openssl genrsa -out goku.key 4096
# openssl req -new -key {private key file} -out {CSR file}
# → Generates a CSR (Certificate Signing Request)
# → Submit to a CA to have an official certificate issued
# Example: openssl req -new -key goku.key -out goku.csr
# openssl req -x509 -new -nodes -key {private key file} -sha256 -days {validity days} -out {certificate file}
# → Generates a self-signed certificate
# → Creates a certificate without CA authentication (for development and testing)
# Example: openssl req -x509 -new -nodes -key goku.key -sha256 -days 365 -out goku.crt
# openssl verify -CAfile {CA bundle file} {certificate file}
# → Verifies that a certificate has been correctly signed by the specified CA
# Example: openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt goku.crt
# openssl pkcs12 -export -out {P12 file} -inkey {private key} -in {certificate} -certfile {intermediate CA certificate}
# → Bundles a PEM certificate and private key into PKCS#12 format (.p12 / .pfx)
# → Used for importing into Windows servers or configuring certain load balancers
Syntax Reference
| Certificate Type | Validation Level | Description |
|---|---|---|
| DV Certificate (Domain Validation) | Domain ownership only | Issued after verifying only that you control the domain. The simplest and fastest to obtain, and available for free from services like Let's Encrypt. Suitable for personal blogs and development environments. |
| OV Certificate (Organization Validation) | Organization verification included | In addition to domain ownership, the CA verifies that the applicant's organization (legal entity) actually exists. The certificate includes the organization name, allowing users to confirm the issuer. Suitable for corporate sites and e-commerce sites. |
| EV Certificate (Extended Validation) | Highest level of organization verification | Issued after a more rigorous review than OV (e.g., checking registration records and phone verification). Browsers used to display a green address bar, but this visual indicator has been removed in modern browsers. Used by financial institutions and major e-commerce sites. |
| Wildcard Certificate | DV or OV | Uses a wildcard in the domain name such as *.example.com, allowing a single certificate to cover multiple subdomains. Simplifies certificate management for services with many subdomains. |
| Multi-Domain Certificate (SAN Certificate) | DV / OV / EV | Uses the SAN (Subject Alternative Name) field to cover multiple different domains with a single certificate. Used when you want to manage several related services under one certificate. |
| Self-Signed Certificate | No CA verification (development use) | A certificate signed by yourself rather than a CA. It can be created instantly at no cost, but browsers will display a "certificate not trusted" warning. Restrict use to development environments and internal systems that are not publicly accessible. |
Examples
Inspect certificate information
# ----------------------------------------------- # Retrieve and inspect a server's certificate information # ----------------------------------------------- # Retrieve TLS certificate information for wp-p.info # The -showcerts option also displays the certificate chain (including intermediate CA certificates) openssl s_client -connect wp-p.info:443 -showcerts </dev/null 2>/dev/null | \ openssl x509 -noout -text | grep -E "Subject:|Issuer:|Not Before:|Not After :"
Running these commands produces the following output:
$ openssl s_client -connect wp-p.info:443 -showcerts </dev/null 2>/dev/null | \
> openssl x509 -noout -text | grep -E "Subject:|Issuer:|Not Before:|Not After :"
Issuer: C=US, O=Let's Encrypt, CN=R11
Validity
Not Before: Jan 10 00:00:00 2025 GMT
Not After : Apr 10 23:59:59 2025 GMT
Subject: CN=wp-p.info
The following example demonstrates this:
# ----------------------------------------------- # Inspect a local certificate file # ----------------------------------------------- # Display detailed information from a PEM certificate file openssl x509 -in /etc/ssl/certs/goku.crt -text -noout # Use the -dates option to check only the expiration dates openssl x509 -in /etc/ssl/certs/goku.crt -noout -dates # Display the Subject Alternative Name (SAN) of the certificate # Useful for checking which domains the certificate covers openssl x509 -in /etc/ssl/certs/goku.crt -noout -ext subjectAltName
Run the following command:
$ openssl x509 -in /etc/ssl/certs/goku.crt -noout -dates
notBefore=Jan 10 00:00:00 2025 GMT
notAfter=Apr 10 23:59:59 2025 GMT
$ openssl x509 -in /etc/ssl/certs/goku.crt -noout -ext subjectAltName
X509v3 Subject Alternative Name:
DNS:goku.example.com, DNS:www.goku.example.com
Create a self-signed certificate (for development)
# ----------------------------------------------- # Create a self-signed certificate for a development environment # ----------------------------------------------- # Step 1: Generate an RSA private key (4096-bit) # Use -out to specify the output file name openssl genrsa -out goku.key 4096 # Step 2: Generate a CSR (Certificate Signing Request) # Enter the domain name or server name as the CN (Common Name) interactively # For development environments, CN=localhost is the common convention openssl req -new -key goku.key -out goku.csr \ -subj "/C=JP/ST=Tokyo/O=KameHouse/CN=localhost" # Step 3: Self-sign the CSR to generate the certificate (valid for 365 days) # -x509 → Generate a self-signed certificate (no submission to a CA) # -nodes → Generate the private key without a passphrase (for automatic server startup) # -sha256 → Use the SHA-256 signature algorithm openssl req -x509 -new -nodes -key goku.key -sha256 -days 365 -out goku.crt \ -subj "/C=JP/ST=Tokyo/O=KameHouse/CN=localhost" # Verify the contents of the generated certificate openssl x509 -in goku.crt -noout -text | head -20
Run the following command:
$ openssl genrsa -out goku.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
.....................++++
.............++++
e is 65537 (0x010001)
$ openssl req -x509 -new -nodes -key goku.key -sha256 -days 365 -out goku.crt \
> -subj "/C=JP/ST=Tokyo/O=KameHouse/CN=localhost"
$ openssl x509 -in goku.crt -noout -text | head -20
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
3a:1f:88:c2:de:4b:9e:07:d5:21:0f:6c:72:a4:55:b3:89:2d:1e:f4
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = JP, ST = Tokyo, O = KameHouse, CN = localhost
Validity
Not Before: Mar 25 00:00:00 2026 GMT
Not After : Mar 25 00:00:00 2027 GMT
Subject: C = JP, ST = Tokyo, O = KameHouse, CN = localhost
Generate a CSR and submit it to a Certificate Authority
# ----------------------------------------------- # Generate a CSR for a production environment and submit it to a CA # (using the vegeta.example.com domain as an example) # ----------------------------------------------- # Step 1: Generate a production RSA private key # Secure the private key carefully in production (chmod 600 recommended) openssl genrsa -out vegeta.key 4096 chmod 600 vegeta.key # Step 2: Generate a CSR that includes a SAN (Subject Alternative Name) # Modern CAs treat a CN-only CSR as having no SAN, # so use -addext to explicitly specify the SAN openssl req -new -key vegeta.key -out vegeta.csr \ -subj "/C=JP/ST=Tokyo/O=SaiyaJinElite/CN=vegeta.example.com" \ -addext "subjectAltName=DNS:vegeta.example.com,DNS:www.vegeta.example.com" # Verify the contents of the generated CSR # Submit this CSR file to your CA (e.g., Let's Encrypt or a commercial CA) openssl req -in vegeta.csr -noout -text | grep -A2 "Subject Alternative Name"
Run the following command:
$ openssl req -in vegeta.csr -noout -text | grep -A2 "Subject Alternative Name"
Requested Extensions:
X509v3 Subject Alternative Name:
DNS:vegeta.example.com, DNS:www.vegeta.example.com
Overview
The TLS handshake that establishes an SSL/TLS connection proceeds roughly as follows. (1) The client sends the server a list of supported TLS versions and cipher suites. (2) The server returns its certificate and public key. (3) The client follows the certificate chain to verify the CA's signature. (4) The public key is used to securely exchange a symmetric key. (5) All subsequent communication is encrypted using a symmetric cipher (such as AES). This mechanism ensures that even if a third party intercepts the communication, they cannot read the contents. The certificate chain is a trust hierarchy from the server certificate to the intermediate CA certificate to the root CA certificate. Browsers verify this chain starting from the root CA certificate store that is built into the browser. For obtaining certificates in production, the free DV certificates provided by Let's Encrypt (Certbot) are widely used. For how to configure an obtained certificate in Nginx, see SSL/TLS Configuration in Nginx.
If you find any errors or copyright issues, please contact us.