Public Key Infrastructure Lab
1 Overview
The learning objective of this lab is for students to get familiar with the concepts in the Public-Key encryption and Public-Key Infrastructure (PKI). After finishing the lab, students should be able to gain a first-hand experience on public-key encryption, digital signatures, public-key certificates, certificate authorities, and authentication based on PKI. Moreover, students will be able to use tools and write programs to create secure channels using PKI.
This lab covers the following topics:
- Public-key encryption
- Public-Key Infrastructure (PKI)
- Certificate Authority (CA) and root CA
- X.509 certificate and self-signed certificate
- Apache, HTTP, and HTTPS
- Man-in-the-middle attacks
Related Readings. Detailed coverage of PKI can be found in the following:
- Chapter 23 of the SEED Book, Computer & Internet Security: A Hands-on Approach, 2nd Edition, by Wenliang Du. See details at https://www.handsonsecurity.net
2 Lab Enviroment
2.1 OpenSSL
In this lab, we will generate public-key certificates, and then use them to secure web servers. The certificate generation tasks will be conducted on the VM, but we will use a container to host the web server.
2.2 DNS Setup
In this document, we use www.bank32.com as an example to show how to set up an HTTPS web server with this name. You need to use a different name for the lab. Use your ubit name and the year to specify the server. For example, if John Smith (UBIT josmit2) does this lab in 2020, the server name should be www.josmit22020.com. You do not need to own this domain; you just need to map this name to the container’s IP address by adding the following entries to /etc/hosts (the first entry is required, otherwise, the example in this lab description will not work):
10.9.0.80 www.bank32.com
10.9.0.80 www.josmit22020.com
2.3 Container Setup
Download the labsetup file from SEED Labs here: https://seedsecuritylabs.org/Labs_20.04/Files/Crypto_PKI/Labsetup.zip
3 Lab Tasks
3.1 Task 1: Become a Certificate Authority (CA)
A Certificate Authority (CA) is a trusted entity that issues digital certificates. The digital certificate certifies the ownership of a public key by the named subject of the certificate. A number of commercial CAs are treated as root CAs; VeriSign is the largest CA at the time of writing. Users who want to get digital certificates issued by the commercial CAs need to pay those CAs.
In this lab, we need to create digital certificates, but we are not going to pay any commercial CA. We will become a root CA ourselves, and then use this CA to issue certificate for others (e.g. servers). In this task, we will make ourselves a root CA, and generate a certificate for this CA. Unlike other certificates, which are usually signed by another CA, the root CA’s certificates are self-signed. Root CA’s certificates are usually pre-loaded into most operating systems, web browsers, and other software that rely on PKI. Root CA’s certificates are unconditionally trusted.
The Configuration File (openssl.conf)
In order to use OpenSSL to create certificates, you have to have a configuration file. The configuration file usually has an extension .cnf. It is used by three OpenSSL commands: ca, req and x509. The manual page of openssl.conf can be found using Google search. You can also get a copy of the configuration file from /usr/lib/ssl/openssl.cnf
with the command.
$ cp /usr/lib/ssl/openssl.cnf .
After copying this file into your current directory, you need to create several sub-directories and files as specified in the configuration file (look at the [CA default] section):
$ mkdir demoCA //base directory where everything is kept
$ mkdir demoCA/certs //directory where issued certs are kept
$ mkdir demoCA/crl //directory where the issued crl are kept
$ mkdir demoCA/newcerts //directory for new certs
$ touch demoCA/index.txt //database index file
$ echo 1000 > demoCA/serial //file with the current serial number
Certificate Authority (CA)
As we described before, we need to generate a self-signed certificate for our CA. This means that this CA is totally trusted, and its certificate will serve as the root certificate. You can run the following command to generate the self-signed certificate for the CA:
$ openssl req -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf
You will be prompted for information and a password. Do not lose this password, because you will have to type it each time you want to use this CA to sign certificates for others. You will also be asked to fill in some information, such as the Country Name, Common Name, etc. - the values that you enter are not important, but you should write them down. The output of the command are stored in two files: ca.key and ca.crt. T he file ca.key contains the CA’s private key, while ca.crt contains the public-key certificate.
We can use the following commands to look at the decoded content of the X509 certificate and the RSA key (-text means decoding the content into plain text; -noout means not printing out the encoded version):
openssl x509 -in ca.crt -text -noout
openssl rsa -in ca.key -text -noout
Please run the above commands. From the output, please identify the followings:
- What part of the certificate indicates this is a CA’s certificate?
- What part of the certificate indicates this is a self-signed certificate
Deliverables
In your lab report, include the following:
- What is a CA?
- Why are CA's important? What part of the CIA triad to they help to support?
- Include a screenshot of the CA certificate with the area indicating that it is a CA cert highlighted.
- Include a screenshot of the CA certificate with the area indicating it is self-signed highlighted.
3.2 Task 2: Create and deploy a Certificate for your web server
A company called bank32.com
(replace this with the name of your own web server) wants to get a publickey certificate from our CA. First it needs to generate a Certificate Signing Request (CSR), which basically includes the company’s public key and identity information. The CSR will be sent to the CA, who will verify the identity information in the request, and then generate a certificate. The command to generate a CSR is quite similar to the one we used in creating the self-signed certificate for the CA. The only difference is the -x509 option
. Without it, the command generates a request; with it, the command generates a self-signed certificate. The following command generate a CSR for www.bank32.com
(you should use your own server name):
openssl req -newkey rsa:2048 -sha256 \
-keyout server.key -out server.csr \
-subj "/CN=www.bank32.com/O=Bank32 Inc./C=US" \
-passout pass:dees
The command will generate a pair of public/private key, and then create a certificate signing request from the public key. We can use the following command to look at the decoded content of the CSR and private key files:
openssl req -in server.csr -text -noout
openssl rsa -in server.key -text -noout
Adding Alternative names
Many websites have different URLs. For example, www.example.com, example.com, example.net, and example.org are all pointing to the same web server. Due to the hostname matching policy enforced by browsers, the common name in a certificate must match with the server’s hostname, or browsers will refuse to communicate with the server. To allow a certificate to have multiple names, the X.509 specification defines extensions to be attached to a certificate. This extension is called Subject Alternative Name (SAN). Using the SAN extension, it’s possible to specify several hostnames in the subjectAltName field of a certificate. To generate a certificate signing request with such a field, we can put all the necessary information in a configuration file or at the command line. We will use the command-line approach in this task. We can add the following option to the "openssl req" command. It should be noted that the subjectAltName extension field must also include the one from the common name field; otherwise, the common name will not be accepted as a valid name.
-addext "subjectAltName = DNS:www.bank32.com, \
DNS:www.bank32A.com, \
DNS:www.bank32B.com"
Please add two alternative names to your certificate signing request. They will be needed in the tasks later.
Deliverables
In your lab report, include the following:
- Include a screenshot of the signing request for your server with the requested extensions.
- Include a screenshot of the key file for your server.
- In addition to DNS records, what else can you use SANs to secure?
3.3 Generating a Certificate for your server
The CSR file needs to have the CA’s signature to form a certificate. In the real world, the CSR files are usually sent to a trusted CA for their signature. In this lab, we will use our own trusted CA to generate certificates. The following command turns the certificate signing request (server.csr) into an X509 certificate (server.crt), using the CA’s ca.crt and ca.key:
openssl ca -config myCA_openssl.cnf -policy policy_anything \
-md sha256 -days 3650 \
-in server.csr -out server.crt -batch \
-cert ca.crt -keyfile ca.key
In the above command, myCA_openssl.cnf
is the configuration file we copied from /usr/lib/ssl/openssl.cnf
. We use the policy_anything
policy defined in the configuration file. This is not the default policy. The default policy has more restriction, requiring some of the subject information in the request to match those in the CA’s certificate. The policy used in the command, as indicated by its name, does not enforce any matching rule.
Copy the extension field
For security reasons, the default setting in openssl.cnf
does not allow the openssl ca
command to copy the extension field from the request to the final certificate. To enable that, we can go to our copy of the configuration file, uncomment the following line:
# Extension copying option: use with caution.
copy_extensions = copy
After signing the certificate, please use the following command to print out the decoded content of the certificate, and check whether the alternative names are included.
openssl x509 -in server.crt -text -noout
Deliverables
In your lab report, include the following:
- Include a screenshot of the certificate file for your server.
- Why couldn't we use the default signing policy for this part of the lab?
3.4 Deploying Certificate in an Apache-Based HTTPS Website
In this task, we will see how public-key certificates are used by websites to secure web browsing. We will set up an HTTPS website based on Apache. The Apache server, which is already installed in our container, supports the HTTPS protocol. To create an HTTPS website, we just need to configure the Apache server, so it knows where to get the private key and certificates. Inside our container, we have already set up an HTTPS site for bank32.com. Students can follow this example to set up their own HTTPS site.
An Apache server can simultaneously host multiple websites. It needs to know the directory where a website’s files are stored. This is done via its VirtualHost file, located in the /etc/apache2/ sites-available directory. In our container, we have a file called bank32 apache ssl.conf, which contains the following entry:
The above example sets up the HTTPS site https://www.bank32.com
(port 443 is the default HTTPS port). The ServerName entry specifies the name of the website, while the DocumentRoot entry specifies where the files for the website are stored. Using the ServerAlias entries, we allow the website to have different names. You should also provide two alias entries.
We also need to tell Apache where the server certificate (Line 1) and private key (Line 2) are stored. In the Dockerfile, we have already included the commands to copy the certificate and key to the /certs folder of the container.
In order to make the website work, we need to enable Apache’s ssl module and then enable this site. They can be done using the following commands, which are already executed when the container is built.
# a2enmod ssl // Enable the SSL module
# a2ensite bank32_apache_ssl // Enable the sites described in this file
Starting the Apache server
The Apache server is not automatically started in the container, because of the need to type the password to unlock the private key. Let’s go to the container and run the following command to start the server (we also list some related commands if you need to stop or restart the server during the lab):
// Start the server
# service apache2 start
// Stop the server
# service apache2 stop
// Restart a server
# service apache2 restart
When Apache starts, it needs to load the private key for each HTTPS site. Our private key is encrypted, so Apache will ask us to type the password for decryption. Inside the container, the password used for bank32 is dees. Once everything is set up properly, we can browse the web site, and all the traffic between the browser and the server will be encrypted.
Please use the above example as a guide to set up an HTTPS server for your website. Please describe the steps that you have taken, the contents that you add to Apache’s configuration file, and the screenshots of the final outcome showing that you can successfully browse the HTTPS site.
Shared folder between VM and Container
In this task, we need to copy files from the VM to the container. To avoid repeatedly recreating containers, we have created a shared folder between the VM and container. When you use the Compose file inside the Labsetup folder to create containers, the volumes sub-folder will be mounted to the container. Anything you put inside this folder will be accessible from inside of the running container
3.4.2 Browsing the website
Now, point the browser to your web server (note: you should put https at the beginning of your URL, instead of using http). Please describe and explain your observations. Most likely, you will not be able to succeed, this is because ... (the reasons are omitted here; students should provide the explanation in their lab reports). Please fix the problem and demonstrate that you can successfully visit the HTTPS website.
In the following, we provide instructions on how to load a certificate into Firefox. We intentionally do not explain why and what certificate should be loaded; students need to figure that out. To manually add a certificate to the Firefox browser, type the following URL in the address bar, and click the View Certificates button on the page (scroll to the bottom).
about:preferences#privacy
In the Authorities tab, you will see a list of certificates that are already accepted by Firefox. From here, we can import our own certificates. After choosing the certificate file, please select the following option: “Trust this CA to identify web sites”. You will see that our certificate is now in Firefox’s list of accepted certificates.
Deliverables
In your lab report, include the following:
- A list of steps taken (files edited/created, commands run).
- A screenshot of the code added to the Apache configuration file.
- A screenshot showing the results of going to the HTTPS page before 3.4.2. Explain these results and why you get them.
- A screenshot showing the results of going to the HTTPS page after 3.4.2. What changed? Why?.
3.5 Task 5: Man in the Middle Attack
In this task, we will show how PKI can defeat Man-In-The-Middle (MITM) attacks. Figure 1 depicts how MITM attacks work. Assume Alice wants to visit example.com via the HTTPS protocol. She needs to get the public key from the example.com server; Alice will generate a secret, and encrypt the secret using the server’s public key, and send it to the server. If an attacker can intercept the communication between Alice and the server, the attacker can replace the server’s public key with its own public key. Therefore, Alice’s secret is actually encrypted with the attacker’s public key, so the attacker will be able to read the secret. The attacker can forward the secret to the server using the server’s public key. The secret is used to encrypt the communication between Alice and server, so the attacker can decrypt the encrypted communication.
The goal of this task is to help students understand how PKI can defeat such MITM attacks. In the task, we will emulate an MITM attack, and see how exactly PKI can defeat it. We will select a target website first. In this document, we use example.com as the target website, but in the task, to make it more meaningful, students should pick a popular website, such as a banking site and social network site.
Step 1: Setting up the malicious website.
In Task 4, we have already set up an HTTPS website. We will use the same Apache server to impersonate example.com (or the site chosen by students). To achieve that, we will follow the instruction in Task 4 to add a VirtualHost entry to Apache’s SSL configuration file: the ServerName should be example.com, but the rest of the configuration can be the same as that used in Task 4. Our goal is the following: when a user tries to visit example.com, we are going to get the user to land in our server, which hosts a fake website for example.com. If this were a social network website, The fake site can display a login page similar to the one in the target website. If users cannot tell the difference, they may type their account credentials in the fake webpage, essentially disclosing the credentials to the attacker.
Step 2: Becoming the man in the middle
There are several ways to get the user’s HTTPS request to land in our web server. One way is to attack the routing, so the user’s HTTPS request is routed to our web server. Another way is to attack DNS, so when the victim’s machine tries to find out the IP address of the target web server, it gets the IP address of our web server. In this task, we use “attack” DNS. Instead of launching an actual DNS cache poisoning attack, we simply modify the victim’s machine’s /etc/hosts file to emulate the result of a DNS cache poisoning attack (the IP Address in the following should be replaced by the actual IP address of the malicious server).
10.9.0.80 www.example.com
Step 3: Browse the target website
With everything set up, now visit the target real website, and see what your browser would say. Please explain what you have observed.
Deliverables
In your lab report, include the following:
- A screenshot of going to the target website, and what happens.
- An explanation of why that happens.
- An explanation as to why the malicious website can’t prevent it from happening without compromising the certificate authority.
3.6 Task 6: Launching a Man-In-The-Middle Attack with a Compromised CA
In this task, we assume that the root CA created in Task 1 is compromised by an attacker, and its private key is stolen. Therefore, the attacker can generate any arbitrary certificate using this CA’s private key. In this task, we will see the consequence of such a compromise. Please design an experiment to show that the attacker can successfully launch MITM attacks on any HTTPS website. You can use the same settings created in Task 4, but this time, you need to demonstrate that the MITM attack is successful, i.e., the browser will not raise any suspicions when the victim tries to visit a website but lands in the MITM attacker’s fake website instead.
Deliverables
In your lab report, include the following:
- A screenshot of going to the target website and being directed to your malicious site.
4 Submission
You will need to submit a written lab report through UBLearns, containing all of the deliverable elements above, by 8PM on Wednesday. You are encouraged to explore beyond what is required by the lab.
5 Scoring
This section TBA pending Alan approval.