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:
- Authentication – verifying the identity of the other party.
- 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.
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?
| File | Purpose |
|---|---|
rootCA.key | Root CA private key (keep safe) |
rootCA.crt | Root CA certificate (public) |
server.key | Server private key |
server.csr | Server certificate signing request |
server.crt | Server certificate (signed) |
client.key | Client private key |
client.csr | Client CSR |
client.crt | Client certificate (signed) |
rootCA.srl | Serial number file (auto‑generated) |