Public Key Infrastructure (PKI) with OpenSSL

A step‑by‑step guide to understanding and creating your own Certificate Authority

📘 How does PKI work?

Two parties (A and B) wish to communicate securely. The communication involves two phases:

  1. Authentication – verifying the identity of the other party.
  2. Encryption – protecting the data exchanged.

Why authenticate? To prevent impersonation. Why encrypt? To ensure confidentiality.

Initially, A and B do not trust each other. They rely on a trusted third party called a Certificate Authority (CA).

🔐 How a Certificate is Issued

  • Partner B generates a private key (kept secret).
  • B creates a Certificate Signing Request (CSR) containing its public key and identity information.
  • B submits the CSR to the CA.
  • The CA verifies B’s identity (if verification fails, no certificate is issued).
  • If verified, the CA signs the CSR using its own private key and produces a signed certificate (.crt).

🤝 Authentication Phase

  • When A wants to communicate with B, A requests B’s certificate.
  • B sends its certificate.
  • A validates the signature using the CA’s public key (which is pre‑installed in the browser/OS trust store).
  • If the signature is valid, A trusts that B is who it claims to be. Authentication is complete.

🔒 Secure Communication (Encryption)

  • A generates a random session key (symmetric key).
  • A encrypts this session key with B’s public key (extracted from B’s certificate).
  • Only B can decrypt it using its private key.
  • Now both share the same secret symmetric key, and they can communicate using fast symmetric encryption (e.g., AES).

🛠️ How to set up PKI (OpenSSL commands)

Below are the minimal OpenSSL commands to create your own Root CA, server certificate, and client certificate. All files will be created in your current directory.

1. Root Certificate Authority (Self‑Signed)

# Generate the Root CA private key
openssl genrsa -out rootCA.key 4096

# Generate the self‑signed Root CA certificate (interactive prompts)
openssl req -new -x509 -key rootCA.key -out rootCA.crt -days 3650

When prompted, fill in the distinguished name (e.g., Country, State, Org, CN=My Root CA). The certificate is valid for 10 years.

2. Server Certificate

a) Generate server private key and CSR

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr

During the CSR prompts, use the server’s hostname as the Common Name (e.g., myserver.example.com).

b) Sign the server CSR with the Root CA

openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 365

This creates a signed server certificate.

Note: For proper TLS usage you should add extensions (like subjectAltName). If needed, create a small file server.ext with:
subjectAltName = DNS:myserver.example.com
and append -extfile server.ext to the command above.

3. Client Certificate

a) Generate client private key and CSR

openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr

Use a meaningful Common Name (e.g., Alice or client@example.com).

b) Sign the client CSR with the Root CA

openssl x509 -req -in client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out client.crt -days 365

4. Verification

openssl verify -CAfile rootCA.crt server.crt
openssl verify -CAfile rootCA.crt client.crt

Expected output:

server.crt: OK
client.crt: OK

Inspect certificate details:

openssl x509 -in server.crt -text -noout
openssl x509 -in client.crt -text -noout

5. (Optional) Test with a TLS Server

# Terminal 1: start a simple HTTPS server
openssl s_server -cert server.crt -key server.key -accept 8443 -www

# Terminal 2: connect as a client (using root CA for trust)
openssl s_client -connect localhost:8443 -CAfile rootCA.crt

If you want to test mutual TLS (client certificate), add -cert client.crt -key client.key to the s_client command.

📁 What Files Are Created?

FilePurpose
rootCA.keyRoot CA private key (keep safe)
rootCA.crtRoot CA certificate (public)
server.keyServer private key
server.csrServer certificate signing request
server.crtServer certificate (signed)
client.keyClient private key
client.csrClient CSR
client.crtClient certificate (signed)
rootCA.srlSerial number file (auto‑generated)