Enabling Post-Quantum Key Agreements with Nginx
Both Google Chrome¹ and CloudFlare² have announced that they are going to spend effort migrating to quantum-resistant cryptography. As one of the first steps both have implemented Kyber768 + X25519 KEM support.
Thankfully these improvements are not only available to Google and CloudFlare customers. Basically everyone can enable X25519Kyber768(Draft00) support in their web server. If they are using relatively modern OpenSSL 3.x. People at OpenQuantumSafe have written a provider for OpenSSL 3.x that provides amongst many others, Kyber and its hybrid KEM schemes. You can find the provider from here: https://github.com/open-quantum-safe/oqs-provider
Building OQS provider
All you have to do is clone the repository, build and install it.
For example:
git clone https://github.com/open-quantum-safe/oqs-provider cd oqs-provider mkdir build && cd build cmake -S .. cmake --build . sudo cmake --install .
Enabling OQS provider
Open your OpenSSL configuration (on Ubuntu it's located at /etc/ssl/openssl.cnf
).
Just enable the provider by-default, this avoids the need to force software to specifically enable the OQS provider.
# List of providers to load [provider_sect] default = default_sect oqsprovider = oqsprovider_sect ... [default_sect] activate = 1 [oqsprovider_sect] activate = 1
You can check the results using openssl list -kem-algorithms
, it should list at least x25519_kyber768 @ oqsprovider
.
Allowing Kyber hybrid KEMs
Next step is to enable the KEM in nginx's TLS configuration. No other changes need to be made if your distribution and nginx uses OpenSSL 3.
Locate the line that says ssl_ecdh_curve auto;
and replace it with:
ssl_ecdh_curve x25519_kyber768:p384_kyber768:x25519:secp384r1:x448:secp256r1:secp521r1;
The first preference now being X25519Kyber768, then P384Kyber768 for Edge, X25519 for regular clients and the usual for compatibility after that.
After this change, just restart nginx (sudo systemctl restart nginx
).
Checking if your browser has PQ KEM support
X25519Kyber768 has been available in Chrome since Chrome 115 (dev trial) and behind a flag after 118 (chrome://flags#enable-tls13-kyber). It's also behind a flag in Edge (edge://flags#edge-post-quantum-kyber). Chrome has also started a gradual rollout and they're at 10% (as of 30.11.2023).
You can test if your browser has Kyber enabled by visiting CloudFlare's test page. You should see kex=X25519Kyber768Draft00
.
Besides this site I'm not aware of any that would allow one to test both QUIC and PQ KEMs simultaneously.
Firefox does not yet support X25519Kyber768Draft00, there has been some effort.
Result
If you visit your website with an enabled browser you should be seeing Kyber786 being used.
Edge will display something like this:
CloudFlare PQ origin pulls
If you use CloudFlare as a reverse proxy, then you can also enable X25519Kyber768 on the first attempt (to save a round trip) using their API:
curl --request PUT \ --url https://api.cloudflare.com/client/v4/zones/[ ZONE_ID ]/id/cache/origin_post_quantum_encryption \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer [ API_TOKEN ]' \ --data '{"value": "preferred"}'
External references
- https://pq-crystals.org/kyber/index.shtml
- https://www.ietf.org/archive/id/draft-tls-westerbaan-xyber768d00-02.html
- https://blog.cloudflare.com/post-quantum-to-origins/
- https://blog.chromium.org/2023/08/protecting-chrome-traffic-with-hybrid.html
- https://chromestatus.com/feature/5257822742249472
- https://crypto.cloudflare.com/cdn-cgi/trace
- https://github.com/open-quantum-safe/oqs-provider