Tutorial
Building a quantum-safe web application based on a quantum-safe version of OpenSSL
Learn how to build a quantum-safe web application using Apache HTTPD as the web server and proxying client requests through HAProxyQuantum computing is a relatively new and emerging technology with the potential to solve complex problems that are too difficult for classical computers. Although this opens up a lot of opportunities for the greater good, it also poses possible risks to our current systems and communications, especially in the area of cybersecurity.
Today's cryptographic systems that form the building blocks of securing our networks and communications are built based on algorithms and processes that could one day be broken by a cryptographically relevant quantum computer. Quantum-safe cryptography is an active area of research and development working to find new algorithms and prototype solutions that are quantum safe.
In this tutorial, you will learn how to build a quantum-safe web application based on a quantum-safe version of OpenSSL, using Apache HTTPD as the web server and proxying client requests through HAProxy which acts as a reverse proxy. To set up our environment, we have used 2 servers: one to setup and install an Apache server and the other to install HAProxy. You could also have an optional server to act as a root certificate authority (CA) for key and certificate management.
We will be using the lattice-based algorithms CRYSTALS-Dilithium for digital signature algorithm (DSA) and CRYSTALS-Kyber as the Key Encapsulation Mechanism algorithm (KEM).
Building a quantum-safe version of OpenSSL requires that you configure OpenSSL to use implementations of quantum-safe algorithms. OpenSSL provides a mechanism called providers which provides a pluggable model for third-party providers to add their implementations of new algorithms. We will be using the OQS(Open Quantum Safe) provider in this implementation to add quantum safe support to OpenSSL.
We will then go on to build Apache HTTPD and HAProxy using this quantum-safe version of OpenSSL. The Open Quantum Safe(OQS) project is an open source project whose objective is to encourage research and development in the field of quantum safe cryptography. This includes developing implementations of quantum safe algorithms and developing prototypes of applications using these quantum safe implementations.
liboqs is an open source library that is part of the OQS project and focuses on developing implementations for quantum-safe algorithms for key exchange and digital signatures used in public key cryptography. The OQS project relies on National Institute of Standards and Technology's (NIST) "Post-Quantum Cryptography Standardization (PQCS)" to identify quantum-resistant algorithms to use.
Setting up your development environment
For this demo environment, we have used 2 ubuntu 22.04(x86_64) LTS servers to install Apache HTTPD v2.4.57 and HAProxy v2.8.0. The following figure shows a layout of a sample environment.

The foundation for building a quantum-safe application as shown in this tutorial is to build a quantum-safe version of OpenSSL first, and then build HAProxy and Apache HTTPD using this quantum-safe version of OpenSSL. To see how to build and install OpenSSL to use quantum safe algorithms, refer to this quantum-safe OpenSSL tutorial, which uses the liboqs library and oqs-provider library to build OpenSSL v3.x.
When building a quantum-safe version of OpenSSL, make sure you build it in a location that can be accessed during the HTTPD and HAProxy builds by specifying the OPENSSL_PATH variable.
For this demo, we will be creating and using self-signed certificates using dilithium5(which is a signature algorithm under the CRYSTALS-Dilithium category) to create the certificate authority(CA) and server certificates. To establish a TLSv1.3 session using quantum-safe KEM algorithms, we will be using kyber768 and p384_kyber768 to activate Kyber768 and its hybrid variant. Other supported quantum-safe algorithms (KEM/DSA) that are implemented by the oqs-provider can be used to create certificates and for establishing TLS sessions.
Steps
Before you go ahead and work through the steps in this tutorial, make sure you have followed the instructions in this quantum-safe OpenSSL tutorial to build and install a quantum-safe version of OpenSSL. This prerequisite step must be done on the servers where you will be building HAProxy and Apache HTTP.
The instructions in this tutorial have been divided into five steps. Step 1 contains instructions to create a non-root user on Ubuntu. Since we will be using a non-root user to build HAProxy and Apache HTTPD, Step 1 also needs to be completed as a pre-req on both servers. Steps 3 & 4 are related to building Apache HTTPD and Step 5 contains instructions to build and install HAProxy.
- Step 1: Create a non-root user on Ubuntu (on HAProxy & Apache HTTPD servers)
- Step 2: Build and install quantum-safe version of OpenSSL by following the quantum-safe OpenSSL tutorial (on HAProxy & Apache HTTPD servers)
- Step 3: Create CA and server certificates using quantum-safe algorithms (on Apache HTTPD server)
- Step 4: Build and install quantum-safe version of Apache HTTPD (on Apache HTTPD server)
- Step 5: Build and install quantum-safe version of HAProxy (on HAProxy server)
Step 1. Create a non-root user on Ubuntu (on HAProxy & Apache HTTPD servers)
To create a non-root user in Ubuntu, log in to the system using the root user and run the following commands:
Add a new user account to the system and enter a new password for the user when prompted. The prompts for changes to user information can be ignored by hitting
ENTERas it is optional.adduser <username>
Add the new user to the sudo group:
usermod -aG sudo <username>Switch to the new user:
su - <username>
Step 2. Build and install quantum-safe version of OpenSSL (on HAProxy & Apache HTTPD servers)
Follow the steps in the quantum-safe OpenSSL tutorial.
If you prefer, you can define the environment variables which will be used throughout this tutorial in the .bashrc file:
vi $HOME/.bashrc
Enter the following lines, and then save and exit:
export WORKSPACE=$HOME/quantumsafe
export BUILD_DIR=$WORKSPACE/build
export OPENSSL_CONF=$BUILD_DIR/ssl/openssl.cnf
export OPENSSL_MODULES=$BUILD_DIR/lib
Run the following command:
source $HOME/.bashrc
Step 3. Create self-signed keys and certificates using quantum-safe algorithms (on Apache HTTPD server)
After you've built and installed OpenSSL to use quantum-safe algorithms by completing this quantum-safe OpenSSL tutorial, you can create self-signed keys and certificates for the backend HTTPD server.
Before creating the self-signed keys and certificates, verify the liboqs-provider is correctly installed and configured with OpenSSL:
$BUILD_DIR/bin/openssl list -providers -verbose -provider oqsprovider
This command should list the default provider and lib-oqs provider similar to the following sample output.

First, create keys and certificates for the CA and the server using quantum-safe algorithms.
Create the CA key and certificate. We will be using the signature algorithm
dilithium5to create the CA key. For the subject of the certificate, we set the following value:"/CN=oqstest CA"(It can be any value, as long as it is not the same common name as the server certificate).cd $WORKSPACE $BUILD_DIR/bin/openssl req -x509 -new -newkey dilithium5 -keyout CA.key -out CA.crt -nodes -subj "/CN=oqstest CA" -days 365 -config $BUILD_DIR/ssl/openssl.cnfCreate the server key and certificate. Replace the hostname defined in the
subjparameter to the correct hostname for your server server (for example,-subj “/CN=c92989v1.ibm.com”).$BUILD_DIR/bin/openssl req -new -newkey dilithium5 -keyout server.key -out server.csr -nodes -subj "/CN=<hostname>" -config $BUILD_DIR/ssl/openssl.cnf $BUILD_DIR/bin/openssl x509 -req -in server.csr -out server.crt -CA CA.crt -CAkey CA.key -CAcreateserial -days 365Create the certificate chain.
cat server.crt > qsc-ca-chain.crt cat CA.crt >> qsc-ca-chain.crtNext, verify that the TLS connection is using the OpenSSL certificates that you just created. To test this, we will start a simple HTTP server using an openssl s_server session.
Start the TLS server provided by OpenSSL in a separate terminal.
$BUILD_DIR/bin/openssl s_server -cert $WORKSPACE/server.crt -key $WORKSPACE/server.key -www -tls1_3 -CAfile $WORKSPACE/CA.crt -curves kyber512:p521_kyber1024From the original terminal, start an openSSL client session to test the TLS connection to the openssl s_server session started above. The output should contain the certificate chain and server certificate as shown below. Press
Ctrl + Cto exit:$BUILD_DIR/bin/openssl s_client -CAfile $WORKSPACE/qsc-ca-chain.crt -groups p521_kyber1024You should see the output similar to the one in the figure below, displaying the quantum-safe KEM and signature algorithms used.

Test the TLS connection by sending curl requests to the s_server session. (Replace the
<hostname>with the hostname used in thesubjparameter in step 3.2 to create the server certificate.)$BUILD_DIR/bin/curl -v --cacert $WORKSPACE/qsc-ca-chain.crt --curves kyber512:p521_kyber1024 https://<hostname>:4433You should see the output similar to the one in the figure below, displaying the quantum-safe KEM and signature algorithms used.

Stop the TLS server that you started in Step 3.4 by entering
Ctrl + C.
Step 4. Build and install quantum-safe Apache HTTPD (on Apache HTTPD server)
In this step, we will build, install, and configure Apache HTTPD, a free, open-source, web based HTTP server. We will build Apache HTTPD using the quantum-safe OpenSSL version we built earlier and configure the server to use the certificates we created in the previous step. We will test this setup by sending curl requests to the HTTPD server and verify the TLS connection.
Build and install Apache HTTPD using quantum-safe OpenSSL.
export HTTPD_PATH=$WORKSPACE/httpd export HTTPD_VERSION=2.4.57 export APR_VERSION=1.7.4 export APRU_VERSION=1.6.3 export APR_MIRROR="https://dlcdn.apache.org"Compiling HTTPD requires
aprandapr-util(Apache Portable Runtime) to be already installed on the system. The commands below install these requirements and also builds and installs HTTPD. (For more information about the commands, refer to the official documentation)cd $WORKSPACE # Install pre-req libraries required for building HTTPD. sudo apt install -y libexpat1-dev libpcre3 libpcre3-dev git clone --branch 2.4.57 https://github.com/apache/httpd.git ${HTTPD_PATH}-${HTTPD_VERSION} cd ${HTTPD_PATH}-${HTTPD_VERSION} # Download both APR and APR-Util from Apache APR, unpack them into # `${HTTPD_PATH}-${HTTPD_VERSION}/srclib/apr` and # `${HTTPD_PATH}-${HTTPD_VERSION}/srclib/apr-util` respectively. mkdir srclib/apr mkdir srclib/apr-util wget https://dlcdn.apache.org/apr/apr-1.7.4.tar.gz && tar xzvf apr-1.7.4.tar.gz -C ${HTTPD_PATH}-${HTTPD_VERSION}/srclib/apr --strip-components 1 wget https://dlcdn.apache.org/apr/apr-util-1.6.3.tar.gz && tar xzvf apr-util-1.6.3.tar.gz -C ${HTTPD_PATH}-${HTTPD_VERSION}/srclib/apr-util --strip-components 1 ./buildconf --with-apr=${HTTPD_PATH}-${HTTPD_VERSION}/srclib/apr --with-apr-util=${HTTPD_PATH}-${HTTPD_VERSION}/srclib/apr-util ./configure --with-included-apr --prefix=${HTTPD_PATH} \ --enable-debugger-mode \ --enable-ssl --with-ssl=${BUILD_DIR} \ --enable-ssl-staticlib-deps \ --enable-mods-static=ssl && \ make && make install;Configure HTTPD server to handle HTTP requests
In this step we need to update the httpd configuration file to handle HTTP requests. The changes shown below are the updates made to the applicable configuration options in httpd.conf. We can use the provided/default values for the rest of the configuration options.
When starting the HTTPD server as a non-root user, there are couple of things to note:
- All ports that the user listens to must be greater than 1024
All directories and files that the server creates or edits should have write permission for the non-root user
Edit the HTTPD configuration file located at
$HTTPD_PATH/conf/httpd.conf(search for the configuration options listed below in the httpd.conf file and make the updates). In this file we update the following configurations (make sure to replace the entries within<>with the correct values for your environment):Listen- port that HTTPD server listens to for HTTP requestsUserandGroup- non-root user and group that is used to run the HTTP serverServerName- hostname of the HTTPD server and port number > 1024 to listen for http requestsDocumentRootandDirectory- location of the index.html to serve when the HTTPD server receives HTTP requests. The directories defined below will be created in the next step along with a new index.html.
Listen <2080> User <username> Group <username> ServerName <c92989v1.ibm.com>:<2080> DocumentRoot "</home/username/quantumsafe/httpd/htdocs/mydocs>" <Directory "</home/username/quantumsafe/httpd/htdocs/mydocs>"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>Create the following directory that will host the document (index.html) which will be served when HTTP requests are made.
mkdir $HTTPD_PATH/htdocs/mydocs vi $HTTPD_PATH/htdocs/mydocs/index.htmlEnter anything you want to display in the index.html.
<html><body><h1>Enter anything here!!</h1></body></html>Start the HTTPD server:
$HTTPD_PATH/bin/apachectl -k startTest that HTTP requests work(Replace the
<hostname>:<port number>with the ServerName configuration option specified in the httpd configuration file above:http://c92989v1.ibm.com:2080). You should see the text entered in the index.html displayed here when the curl requests are made.$BUILD_DIR/bin/curl http://<hostname>:<port number>
Step 5. Build and install quantum-safe HAProxy
HAProxy is a very popular open source based reverse proxy offering load balancing capabilities for both TCP and HTTP traffic. In addition to acting as a load balancer, it also helps secure traffic using TLS through techniques like SSL Passthrough or SSL termination. In SSL termination, the traffic encryption/decryption is handled at the HAProxy side(edge proxy), allowing unencrypted traffic to flow to the backend web servers. The TLS certificates of backend servers can also be managed at the HAProxy side. In the SSL Passthrough case, HAProxy just allows the encrypted traffic to pass through it without making any changes to the traffic flowing. In this case, the backend servers deal with encrypting and decrypting the traffic.
In this step, we will show you how to build HAProxy using quantum-safe enabled OpenSSL and configure HAProxy to perform SSL termination. (Before working on this step, make sure you have completed all the pre-reqs.)
We will install and run HAProxy as a non-root user for the purposes of this tutorial. When starting the HAProxy server as a non-root user, there are couple of things to note:
- All ports that the user listens to must be greater than 1024
All directories and files that the server creates or edits should have write permission for the non-root user
Build HAProxy using quantum-safe OpenSSL.
cd $WORKSPACE git clone --branch v2.8.0 https://github.com/haproxy/haproxy.git cd $WORKSPACE/haproxy make TARGET=generic \ SSL_INC=$BUILD_DIR/include \ SSL_LIB=$BUILD_DIR/lib64 \ USE_OPENSSL=1Copy the server and CA certificates from the Apache server to the HAProxy server side:
Create a directory to store the server certificate:
mkdir $WORKSPACE/haproxy/certs; cd $WORKSPACE/haproxy/certsCopy server certificates from the Apache server to the HAProxy server((server.crt, server.key, qsc-ca-chain.crt)). Replace the
<username>:<hostname>with the non-root user we created earlier and the hostname of the Apache HTTPD server from where we want to fetch the certificates:scp <username>@<hostname>:$WORKSPACE/server.crt . scp <username>@<hostname>:$WORKSPACE/server.key . scp <username>@<hostname>:$WORKSPACE/qsc-ca-chain.crt .Place both the server key and certificate in a PEM formatted file and update the permissions of the file:
cat server.crt server.key >> server.pem chmod 755 server.pem
Create a configuration file for HAProxy. The HAProxy configuration file consists of mainly four sections: global, default, frontend and backend.
The
globalsection defines the configurations that affect the overall working and performance of the HAProxy service. For example, some of the settings we define in this section include where to direct log messages, maximum connections that HAProxy will accept, user/group settings to tell HAProxy to drop privileges after initialization and stats setting to enable the Runtime API which can be used to dynamically configure HAProxy.The
defaultsection defines the default settings for configurations related to how HAProxy receives and processes client requests. For example, the default settings for timeouts, maxconnections, mode (tcp or http), etc. Thefrontendsection is used to set configurations related to where a user can send client requests to. This is useful when HAProxy is used as a reverse proxy to send client requests to backend servers. Thebackendsection defines configurations related to the backend server that HAProxy will send the client requests to. For example, in the case of SSL termination, HAProxy terminates the SSL connection based on the configuration specified in the frontend sectionbind <ip>:<port> ssl crtand can inspect and modify things like HTTP headers and route traffic to different backend servers based on URL. The HAProxy documentation provides details about the different configuration options, if interested.Below is the HAProxy configuration file for enabling SSL termination by HAProxy. The SSL connection will be terminated at the edge proxy(HAProxy) and unencrypted traffic will be sent to the backend server(Apache HTTPD).
Create a new configuration file for HAProxy:
cd $WORKSPACE/haproxy vi haproxy_ssl_termination.cfgCopy and paste the configuration below into your HAProxy configuration file (make sure to replace the entries within
<>with the correct values for your environment):- In the frontend section, you can specify any port > 1024 to handle http request (e.g:
bind *:8080and https request(e.g:bind *:8043) - In the frontend section, make sure you specify the correct location of the server.pem file at the HAProxy side as specified in the
bind *:8043parameter - In the backend section, change the hostname as specified in the
serverparameter to reflect your HTTPD ipaddress, and port number to reflect the port number that the HTTPD server is listening to for HTTP requests. (Format is: `server: )
global maxconn 50000 log 127.0.0.1:2514 local2 ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 ssl-default-bind-options ssl-min-ver TLSv1.3 defaults mode http log global timeout connect 10s timeout client 1m timeout server 1m frontend web-frontend bind *:<8080> bind *:<8043> ssl curves kyber1024:kyber768:kyber512:p521_kyber1024 crt </home/username/quantumsafe/haproxy/certs/server.pem> http-request redirect scheme https unless { ssl_fc } default_backend web-backend backend web-backend balance roundrobin server <c92989v1> <9.30.26.134:2080> listen stats bind *:9201 mode http stats enable stats uri /- In the frontend section, you can specify any port > 1024 to handle http request (e.g:
Start HAProxy server in the background.
./haproxy -f haproxy_ssl_termination.cfg &Connect to the HAProxy server and test the SSL connection. (The hostname must be that of the HAProxy server and the port number is the SSL port it is listening to for HTTPS requests.)
$BUILD_DIR/bin/curl https://<hostname>:<8043> -v -k --curves kyber512:p521_kyber1024
You should also see the quantum-safe algorithms used to encrypt this end-to-end TLS connection.
To stop the HAProxy server, run the command
fg. This brings the HAProxy server running as a background process to the foreground. RunCtrl + Cto exit the process.
Summary and next steps
In this tutorial, we demonstrated how to build a quantum-safe web application using a quantum-safe version of OpenSSL, HAProxy, and Apache HTTPD server. We also demonstrated how to test a secure, end-to-end communication using quantum-safe algorithms.
If you are interested in looking at other protocols like SSH to understand how to make that protocol quantum safe, refer to this quantum-safe SSH tutorial.
You can also learn more about quantum-safe cryptography here, and explore more details in our developer's course on quantum-safe cryptography, “A practical introduction to quantum-safe cryptography”.
Acknowledgements
Thanks to Nigel Jones, Martin Schmatz, Paul Schweigert, and Alex Bozarth for their review and feedback.