Certificates (TLS/SSL) I

Alex Izuka
5 min readJul 26, 2023

SSL (Secure Sockets Layer) and TLS (Transport Layer Security) are cryptographic protocols that are used to secure communication over the Internet. Their primary purpose is to establish a secure and encrypted channel between a client (such as a web browser) and a server, ensuring that data transmitted between them remains confidential and tamper-proof.

Components of a certificate

A certificate is a digital document used in SSL/TLS and other cryptographic protocols to verify the identity of a party (usually a server) and establish secure communication. It contains various components that play a crucial role in the security and authenticity of the certificate. Let’s describe each of the components:

Subject:

  • The Subject field identifies the entity that the certificate is issued to. It typically represents the domain name (for SSL/TLS certificates) or the entity’s name and other information (for other types of certificates).
  • For SSL/TLS certificates, the Subject field is usually the Common Name (CN) field that contains the domain name of the website or server.

Issuer:

  • The Issuer field identifies the entity that issued the certificate. This entity is known as the Certificate Authority (CA).
  • The CA digitally signs the certificate to verify its authenticity. Clients can trust the certificate if they trust the CA that issued it.

Public Key:

  • The Public Key is a crucial component of the certificate. It is used for encrypting data that only the corresponding Private Key can decrypt, ensuring secure communication.
  • The Public Key is made available to clients who want to establish a secure connection with the entity identified in the certificate.

Validity Period:

  • The Validity Period specifies the duration for which the certificate is considered valid. It consists of two dates: the Not Before date and the Not After date.
  • The certificate is considered valid only within this time range. After the Not After date, the certificate is no longer considered trustworthy, and clients should not use it for secure communication.

Signature:

  • The Signature is a cryptographic value generated by the CA using its Private Key. It is applied to the certificate and its contents to create a digital signature.
  • The digital signature ensures the integrity of the certificate. Clients can verify the authenticity of the certificate by verifying its signature using the CA’s Public Key.

The overall process of validating a certificate involves the client verifying the certificate’s signature against the CA’s Public Key and then checking the certificate’s validity period and Subject information to ensure it matches the server it is connecting to.

Enabling SSL in Nginx and Apache

Nginx

Step 1: Install Nginx and OpenSSL: We do that with the commands below.

sudo apt update
sudo apt install nginx openssl

Step 2: Generate a self-signed SSL certificate: We use the command below for that.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt -subj "/CN=your_domain.com"

Step 3: Configure Nginx to use SSL: Edit the Nginx configuration file (usually located at /etc/nginx/sites-available/default or /etc/nginx/nginx.conf): We do the editing below.

server {
listen 443 ssl;
server_name your_domain.com;

ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

location / {
# Your website configuration here
}
}

server {
listen 80;
server_name your_domain.com;
return 301 https://$host$request_uri;
}

Step 4: Restart Nginx to apply the changes: We use the commands below for that.

sudo service nginx restart

Apache

Regarding installing SSL in Apache, we use the steps below.

Step 1: Install Apache and OpenSSL: We do that using the commands below.

sudo apt update
sudo apt install apache2 openssl

Step 2: Generate a self-signed SSL certificate: We use the command below for that.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt -subj "/CN=your_domain.com"

Step 3: Enable Apache SSL module and configure SSL: We use the command below for that.

sudo a2enmod ssl

Step 4: Configure Apache to use SSL: Just as we did with Nginx, we do the same for Apache, We edit the Apache virtual host configuration file (usually located at /etc/apache2/sites-available/default-ssl.conf):

<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html

SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.crt
SSLCertificateKeyFile /etc/apache2/ssl/apache.key

<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>

# Your website configuration here
</VirtualHost>
</IfModule>

Step 5: Enable the virtual host and restart Apache: We use the commands below for that.

sudo a2ensite default-ssl
sudo service apache2 restart

Handshake Protocol

The SSL/TLS handshake protocol is a crucial process that occurs when a client (e.g., a web browser) and a server (e.g., a web server) initiate a secure connection. This handshake establishes the parameters for secure communication, authenticates the server to the client (optional client authentication can also be performed), and generates session keys used for encryption and decryption of data.

We illustrate the usage below (Make sure you have OpenSSL installed on both the client and server systems.)

Step 1: Generate Certificates and Private Keys: We’ll generate self-signed certificates for both the client and server for demonstration purposes. In other scenarios, you’d obtain certificates from a trusted Certificate Authority (CA).

On the server:

# Generate a private key for the server
openssl genpkey -algorithm RSA -out server.key

# Generate a self-signed certificate for the server
openssl req -x509 -new -key server.key -out server.crt -subj "/CN=example.com"

On the client:

# Generate a private key for the client
openssl genpkey -algorithm RSA -out client.key

# Generate a self-signed certificate for the client
openssl req -x509 -new -key client.key -out client.crt -subj "/CN=client"

Step 2: Implement the Server: Create a simple TLS server in Python that listens on a port (e.g., 4433) and presents its certificate and private key during the handshake:

# Save this as tls_server.py
import socket
import ssl

def main():
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="server.crt", keyfile="server.key")

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
sock.bind(("0.0.0.0", 4433))
sock.listen(1)

with context.wrap_socket(sock, server_side=True) as ssock:
conn, addr = ssock.accept()
with conn:
print("Connection established with:", addr)
data = conn.recv(1024)
print("Received data:", data.decode())
conn.sendall(b"Hello, client!")

if __name__ == "__main__":
main()

Step 3: Implement the Client: Create a Python script for the client to connect to the server:

# Save this as tls_client.py
import socket
import ssl

def main():
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
context.load_verify_locations(cafile="server.crt")

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
with context.wrap_socket(sock, server_hostname="example.com") as ssock:
ssock.connect(("server_ip_address", 4433))
ssock.sendall(b"Hello, server!")
data = ssock.recv(1024)
print("Received data from server:", data.decode())

if __name__ == "__main__":
main()

Step 4: Run the Server and Client: Run the server and client scripts in separate terminal windows or on different machines. Make sure to replace "server_ip_address" in the client script with the IP address of the machine running the server.

When you run the client script, it will establish a secure connection to the server using the self-signed certificates and perform the SSL/TLS handshake. The server will receive the client’s “Hello, server!” message and respond with “Hello, client!”.

The handshake process involves multiple steps, including exchanging supported cipher suites, generating session keys, and verifying the authenticity of the server’s certificate. The ssl module in Python's standard library handles these details automatically when creating the SSL context.

--

--