Quantum key distribution (QKD) is a key agreement method that relies on the laws of physics and ensures that the keys have not been eavesdropped on or modified by a third party.
QKD equipment (such as IDQ Clavis or Cerberis) is expensive, requires specific infrastructure (2-3 optical fiber links), and has high operational costs.
QKD as a Service, QaaS, allows the users to obtain a shared secret from two remote QKD devices in a secure way. QaaS uses a mix of quantum and classical channels in a way that is sustainable for active attacks on any single communication segment.
This project consists of
- the QaaS itself (
service), - the administration panel (
centis), - the QaaS user library, and
- post-quantum proxy, PQProxy, which can be used to enable quantum-safe (PQC) connections between nodes.
The QaaS user library and PQProxy share the same Java code base inside
userlib+pqproxy.
Following IDQ Clavis notation, we call QKD devices Alice (the transmitter) and Bob (the receiver).
The QaaS servers, which are directly attached to Alice and Bob, are called Aija and Brencis. They can be accessed from the controlling module called Centis.
The users who wish to establish a secure TLS connection based on a shared key received from QaaS are called User 1 and User 2.
Since not all nodes have out-of-the-box TLS support (in some cases we need TLS with PQC), we introduce additional proxies.
The following figure illustrates all the nodes that participate in the QaaS system:
The QaaS infrastructure ensures secure (green) link between User 1 and User 2 by utilizing the optical fiber QKD system (in the bottom) and multiple classical PQC links.
Multiple PQC and ECC keys and certificates have to be generated in order for the whole QaaS system could operate in a secure way. We use web sockets in our protocols, meaning that keys and certificates ensure the secure web sockets protocol over TLS (wss) instead of plain web sockets (ws), like https is a secure version of http.
In order to be able to generate keys and sign certificates, OpenSSL with post-quantum algorithms (from LibOQS) has to be installed. For OpenSSL 1.1.1, use our scripts from https://github.com/LUMII-Syslab/oqs-haproxy. For OpenSSL 3, install oqs-provider from https://github.com/open-quantum-safe/oqs-provider.
Then run:
scripts/gen-keys.shAll the keys (for CA, Aija, Brencis, Centis, users, and proxies) are placed into subfolders within ca-scripts. The keys are mostly used by the scripts (from the scripts directory). Some (ECC, non-PQC) keys may be installed in a non-PQC browser, where Centis will be launched (see below).
The code from the service project is intended to be launched on the servers with directly attached QKD devices (however, we provide two types of QKD device simulators for experiments and tests; see below how to configure them).
In order to install all prerequisites (Golang compiler) on Ubuntu, run:
sudo apt install golang-go libzmq5-dev(on older Ubuntu, install libzmq-dev).
We need golang at least 1.16. If your go version shows less, then install Go as follows:
sudo add-apt-repository ppa:longsleep/golang-backports -y
sudo apt upgrade golangIn order to install prerequisites on macOS, run:
brew install golangOn Windows, we recommend to use WSL2 and Ubuntu. Run
C:\Windows\System32\bash.exe
and follow the Ubuntu-related instructions.
You will also need to set up port forwarding from Windows to the Go server running under WSL2. To do that, find out the IP of WSL2:
C:\Windows\System32\bash.exe -c "ifconfig | grep -o 'inet [^ ]*' | sed -n '1s/.* \([^ ]*\).*/\1/p'"or (if that doesn't work):
C:\Windows\System32\bash.exe -c "ifconfig"Then, run
cmd.exeas administrator, and type:netsh interface portproxy add v4tov4 listenport=[PORT] listenaddress=0.0.0.0 connectport=[PORT] connectaddress=[WSL_IP]for each Go port (default are 8001 for Aija and 8002 for Brencis) and the WSL2 IP obtained above.
Finally, regardless of your OS, from the service directory execute go mod tidy to install Go packages:
cd service
go mod tidyEdit config.toml to configure the QaaS service. Typically, the service serves one endpoint - either Aija or Brencis. However, in the experimental environment, both can be launched at once.
Aija and Brencis are launched as non-secure web socket servers (upgraded HTTP). Specify aija_port (recommended 8001), brencis_port (recommended 8002), or both. Besides, specify the gatherer, which will be used to collect keys. Possible values are:
clavis- uses the real IDQ Clavis device to collect quantumly distributed keys; in this case, also specify theclavis_urlproperty;pseudorandom- generates keys randomly (both Aija and Brencis must be launched from the same process, i.e., bothaija_portandbrencis_porthave to be specified);filesystem- takes keys from the file system folder (the folder can be shared); specify the folder path in thefs_gatherer_dirproperty. File names must be in the format<key-ID>.key(e.g.,00f2b5c1-0284-4fc9-8d7d-d663f31c7d7c.key) and the content must be the 256-bit binary key (32 bytes long).
We have prepared a script for launching 4 reverse proxies (2 in front of Aija and 2 in front of Brencis) to enforce PQC connections from Users 1 and 2 and from Centis (Centis has separate proxies since it can control Aija and Brencis; Centis has a specific client key+certificate).
In order to launch Aija and Brencis in the PQC mode (i.e., with all 4 proxies), run:
../scripts/aija+brencis.shThe script launches several copies of the default terminal app for the OS (gnome-terminal on Linux, Terminal on macOS, and cmd with Cygwin on Windows).
In order to launch Aija and Brencis in the non-secure web socket mode (without proxies), run:
go run .
In order to install all prerequisites (npm) on Ubuntu, run:
sudo apt install npmIn order to install prerequisites on macOS, run:
brew install npmThen from the centis directory, launch:
npm installFrom the scripts directory, launch:
../centis.shThe script launches 2 local HTTP-to-PQC/HTTPS proxies. Besides, the script launches the Node.js backend for Centis. The browser pointing to http://localhost:3000/qkdc-service should be opened automatically.
Since two proxies are launched locally, you can use ws://localhost:8080/ws and ws://localhost:8081/ws as addresses for Aija and Brencis.
If you would like to run Centis without proxies, from the
centisdirectory, launch:npm startNotice that in you will need a PQC-enabled browser built with LibOQS.
If you are paranoic, it is possible to launch Centis in HTTPS mode even if your browser does not support PQC. For that, the scripts/gen-keys.sh script has also generated non-PQC elliptic curve (ECC) keys and certificates that have to be installed in your non-PQC browser:
- Install
ca_scripts/proxy-client-centis/proxy-client-centis.pemas a client key to be used to authenticate in web sites. - Install
ca_scripts/proxy-ca/ca.crtas a trusted CA to identify websites.
Then edit scripts/pqproxy-local2pqccentis4aija.properties and pqproxy-local2pqccentis4brencis.properties and specify sourceTls=true. Ensure the correct source and target key stores and trust stores are also specified there.
Currently, we provide Java source code for sample implementations of User 1 (the TLS client) and User 2 (the TLS server). The symmetric TLS key is obtained from Aija and Brencis by means of the Butterfly Protocol from our paper.
Source files are:
userlib+pqproxy/src/test/java/lv/lumii/test/QkdTestUser1.javaanduserlib+pqproxy/src/test/java/lv/lumii/test/QkdTestUser2.java.
Before launching User 1 and User 2, edit the userlib+pqproxy/qkd.properties file, where the client (User 1) and server (User 2) PQC credentials are specified, as well as Aija and Brencis URLs.
User 2 (the server) can be launched via:
userlib+pqproxy/scripts/user2.shStart User 2 (the server) before User 1 so User 1 does not receive the "connection refused" error.
User 1 can be launched via:
userlib+pqproxy/scripts/user1.shDocs on the internal APIs used between QaaS users and servers can be found at API.md.
Docs on the operation of QaaS service can be found at SERVICE.md.
