Introduction
In this lab, you will explore the fundamentals of Public Key Infrastructure (PKI), the system that underpins much of the security on the internet, including HTTPS. PKI is a set of roles, policies, hardware, software, and procedures needed to create, manage, distribute, use, store, and revoke digital certificates and manage public-key encryption.
You will get hands-on experience with the openssl command-line tool to perform the core functions of a PKI. You will act as your own Certificate Authority (CA), issue a certificate for a web server, verify the certificate's chain of trust, and finally, revoke the certificate. All operations will be performed within the ~/project directory.
Understanding PKI Basics
In this step, we will cover the fundamental concepts of PKI. There are no commands to execute in this step; the goal is to build a solid theoretical foundation before we begin the hands-on practice.
Public Key Infrastructure (PKI)
PKI is a framework designed to enhance security in electronic communications. It uses public-key cryptography to bind public keys with respective user identities by means of a Certificate Authority (CA). This binding is established through a registration and issuance process.
Certificate Authority (CA)
A Certificate Authority is a trusted entity that issues digital certificates. The CA acts as a trusted third party, trusted by both the subject (owner) of the certificate and the party relying upon the certificate. The primary role of the CA is to digitally sign and publish the public key bound to a given user.
Digital Certificate
A digital certificate is an electronic document (often following the X.509 standard) that contains:
- The owner's public key.
- The owner's identifying information (like a name or hostname).
- The issuer's (CA's) information and digital signature.
- A validity period (start and end date).
- A unique serial number.
The CA's signature on the certificate attests that the public key contained in the certificate belongs to the entity named in the certificate.
Trust Chain
A trust chain (or certificate chain) is a sequence of certificates, starting from an end-entity certificate (e.g., for example.com) and ending with a root CA certificate.
- Root CA Certificate: This is a self-signed certificate from the ultimate authority, the Root CA. These certificates are pre-installed in your browser or operating system's "trust store".
- Intermediate CA Certificate(s): Large CAs often use intermediate CAs to issue certificates to end-users, protecting the root key. An intermediate certificate is signed by the root CA.
- End-Entity Certificate: This is the certificate issued to a specific server or user. It is signed by an intermediate CA (or directly by the root CA in simpler setups).
When your browser receives a server's certificate, it verifies the signature by checking the certificate of the issuer. It follows this chain up until it reaches a root CA that is already in its trust store. If the chain is valid and all signatures check out, the server is considered trusted.
In the next step, you will create your own Root CA.
Create a Certificate Authority
In this step, you will act as a Certificate Authority (CA) and create its foundational components: a private key and a self-signed root certificate. All commands will be run in the terminal, and all files will be created in your current directory, ~/project.
First, generate the CA's private key. This key is the most critical secret of the PKI; it is used to sign all certificates issued by the CA.
openssl genpkey -algorithm RSA -out ca.key
Next, you will create a self-signed root certificate. A root certificate is self-signed because it is the ultimate anchor of trust; there is no higher authority to sign it.
Execute the following command to generate the certificate. We use the -subj argument to provide the certificate's subject information non-interactively.
openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.pem -subj "/C=US/ST=California/L=MountainView/O=MyLab/CN=MyLabRootCA"
Let's break down this command:
req: Certificate Signing Request (CSR) and certificate generating utility.-x509: Outputs a self-signed certificate instead of a CSR.-new: Creates a new certificate.-nodes: "No DES", which means the private key will not be encrypted with a passphrase. This is for simplicity in our lab.-key ca.key: Specifies the private key to use for signing.-sha256: Uses the SHA-256 hash algorithm for the signature.-days 365: Sets the certificate's validity period to 365 days.-out ca.pem: Specifies the output file for the new certificate.-subj "/C=.../CN=...": Provides the subject details.CN(Common Name) is the primary identity, which for a CA is its name.
You now have a CA private key (ca.key) and a root certificate (ca.pem). You can inspect the contents of your new CA certificate:
openssl x509 -in ca.pem -text -noout
Scroll through the output and notice the Issuer and Subject fields are identical, confirming it is self-signed.
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
...
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
Validity
Not Before: ...
Not After : ...
Subject: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
Subject Public Key Info:
...
Issue a Server Certificate
In this step, you will simulate a server owner requesting a certificate. You'll generate a private key and a Certificate Signing Request (CSR) for the server, and then use your CA from the previous step to sign the CSR and issue a valid certificate.
First, generate a private key for the server. This key must be kept secret on the server itself.
openssl genpkey -algorithm RSA -out server.key
Next, create a Certificate Signing Request (CSR). A CSR is a block of encoded text containing the public key and other information that will be included in the certificate, such as the organization name and domain name. The CSR is sent to the CA for signing.
openssl req -new -key server.key -out server.csr -subj "/C=US/ST=California/L=MountainView/O=MyWebServer/CN=example.com"
Note that for a server certificate, the CN (Common Name) must match the domain name of the server, in this case, example.com.
Now, acting as the CA, you will sign the server's CSR (server.csr) with your CA's private key (ca.key). This action creates the final server certificate (server.crt).
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.crt -days 300 -sha256
Let's review the new options:
x509 -req: This tells OpenSSL to process a CSR.-in server.csr: The input CSR file.-CA ca.pem: The CA's certificate to use as the issuer.-CAkey ca.key: The CA's private key for signing.-CAcreateserial: This creates and manages a serial number file (ca.srl), which is required to ensure every certificate issued by the CA has a unique serial number.-days 300: The validity for the server certificate. This should be shorter than the CA's certificate validity.
Finally, inspect the newly created server certificate.
openssl x509 -in server.crt -text -noout
In the output, observe the Issuer and Subject fields. The Issuer should be your CA (MyLabRootCA), and the Subject should be your server (example.com). This confirms the certificate was correctly issued by your CA.
Certificate:
Data:
Version: 3 (0x2)
Serial Number: ...
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
Validity
Not Before: ...
Not After : ...
Subject: C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
...
Signature Algorithm: sha256WithRSAEncryption
...
Verify Certificate Chain
In this step, you will learn how to verify a certificate chain. This is the process a client (like a web browser) performs to determine if a server's certificate is trustworthy. The client checks if the certificate was signed by a CA that it trusts.
You can use the openssl verify command to perform this check. You need to tell OpenSSL which CAs you trust by providing the root certificate.
Run the following command to verify the server.crt against your ca.pem root certificate:
openssl verify -CAfile ca.pem server.crt
The output should be:
server.crt: OK
This OK status confirms that:
- The
server.crtcertificate was indeed signed by the private key corresponding to the public key inca.pem. - The certificate has not expired.
Now, let's see what happens if the verifier does not have our CA in its list of trusted CAs. You can simulate this by running the verify command without the -CAfile option.
openssl verify server.crt
This time, the command will fail with an error similar to this:
C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error server.crt: verification failed
The error "unable to get local issuer certificate" means that the system could not find the certificate of the issuer (MyLabRootCA) in its default trust store. This demonstrates why it's essential for clients to have the root CA certificate to establish a chain of trust.
Simulate Certificate Revocation
In this step, you will learn how to revoke a certificate. Revocation is a critical process for when a certificate's private key is compromised, or the certificate is no longer needed before its natural expiration. This is managed using a Certificate Revocation List (CRL).
A CRL is a digitally signed list, issued by a CA, that contains the serial numbers of all certificates it has revoked. Clients can download the CRL to check if a certificate they've received is still valid.
To manage revocation, openssl needs a small configuration file to know where to find the CA's database files (index.txt and serial). The setup script for this lab has already created the necessary directory (my-ca) and files. Now, create the configuration file.
Use the cat command to create my-ca.conf:
cat << EOF > my-ca.conf
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./my-ca
database = \$dir/index.txt
serial = \$dir/serial
private_key = ca.key
certificate = ca.pem
default_md = sha256
policy = policy_anything
crl_extensions = crl_ext
default_crl_days = 30
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ crl_ext ]
authorityKeyIdentifier=keyid:always
EOF
This configuration file tells OpenSSL how to operate as a Certificate Authority. Here's what each section does:
default_ca = CA_default: Points to the main CA configuration section.dir = ./my-ca: CA working directory for database filesdatabase = $dir/index.txt: Certificate database (tracks issued/revoked certificates)serial = $dir/serial: Serial number file for unique certificate IDsprivate_key = ca.key: CA's private key for signing certificatescertificate = ca.pem: CA's own certificate filedefault_md = sha256: Hash algorithm for signatures (SHA-256)policy = policy_anything: Certificate validation rulescrl_extensions = crl_ext: CRL formatting optionsdefault_crl_days = 30: CRL validity period (30 days)countryName = optional: Country codestateOrProvinceName = optional: State/provincelocalityName = optional: City/locationorganizationName = optional: Organization nameorganizationalUnitName = optional: DepartmentcommonName = supplied: Domain/server name (required)emailAddress = optional: Email addressauthorityKeyIdentifier=keyid:always: Includes CA identifier in CRLs for verification
This config file is the "operating manual" for your CA. It tells OpenSSL where to find keys, how to store certificates, and what rules to follow for issuing and revoking certificates.
Now, revoke the server certificate (server.crt). This command will look up the certificate's serial number and mark it as revoked in the index.txt database file.
openssl ca -config my-ca.conf -revoke server.crt
You will see output confirming the revocation.
After revoking, you must generate and publish an updated CRL.
openssl ca -config my-ca.conf -gencrl -out my-ca.crl
This creates the file my-ca.crl, which contains the list of revoked certificates.
Finally, let's try to verify the server certificate again, but this time, we will also provide the CRL. A proper verification process must check for revocation.
openssl verify -CAfile ca.pem -CRLfile my-ca.crl -crl_check server.crt
The command now fails with a clear message:
C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
error 23 at 0 depth lookup: certificate revoked
error server.crt: verification failed
The "certificate revoked" error confirms that our revocation process was successful. The client, when checking the CRL, correctly identified that the certificate for example.com is no longer trustworthy.
Summary
Congratulations! You have successfully completed this lab on the basics of Public Key Infrastructure. You have gained practical experience with the fundamental operations that secure digital communications.
In this lab, you have learned how to:
- Understand the core concepts of PKI, Certificate Authorities, and trust chains.
- Create your own simple Root CA by generating a private key and a self-signed certificate.
- Issue a server certificate by signing a Certificate Signing Request (CSR) with your CA's key.
- Verify a certificate's trust chain using the
openssl verifycommand. - Revoke a certificate and confirm its revoked status by generating and using a Certificate Revocation List (CRL).
These skills are the building blocks for managing secure systems and understanding how trust is established on the internet.



