Thursday, September 11, 2025
Playing with Apache httpd and PQC
At the time of the writing browsers like Firefox and Google Chrome only support PQC for key exchange, curl when compiling with openssl 3.5.x supports the exchange and the cert/key.
Based on my previous post, create a RSA key/cert pair for the browsers.
Create an MLDSA-65 for curl tests:
openssl req \
-x509 \
-newkey mldsa65 \
-keyout localhost-mldsa-65.key \
-subj /CN=localhost \
-addext subjectAltName=DNS:localhost \
-days 30 \
-nodes \
-out localhost-mldsa-65.crt
Configure httpd.conf:
Listen 4433
<VirtualHost *:4433>
SSLEngine on
SSLCertificateFile localhost.crt
SSLCertificateKeyFile localhost.key
# PQC cert/key
SSLCertificateFile localhost-mldsa-65.crt
SSLCertificateKeyFile localhost-mldsa-65.key
</VirtualHost>
Start Apache httpd.
Test with Firefox, accept the self-signed certificate and you will get the "It works!" page.
Test with curl:
curl -k -v https://localhost:4433/
you get:
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ml-dsa-65
Use a curl that doesn't support PQC (compiled with a 3.2.x openssl for example):
curl -k -v https://localhost:4433/
you get:
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / RSASSA-PSS
You can also tell a PQC curl to use x25519 and ask for an RSA key/cert:
curl -k -v --curves X25519 --sigalgs RSA-PSS+SHA256 https://localhost:4433/
Or X25519MLKEM768 and ask for an RSA key/cert:
curl -k -v --curves X25519MLKEM768 --sigalgs RSA-PSS+SHA256 https://localhost:4433/
Playing with openssl 3.5.x and PQC
PQC = Post Quantum Cryptography
PQC can be used in 2 places: the key exchange and the key/cert themselves.
For the moment browsers like firefox and google chrome only supprt the key exchange part.
Create a PQC key/cert using openssl:
openssl req \
-x509 \
-newkey mldsa65 \
-keyout localhost-mldsa.key \
-subj /CN=localhost \
-addext subjectAltName=DNS:localhost \
-days 30 \
-nodes \
-out localhost-mldsa.crt
Start openssl s_server:
openssl s_server \
-cert localhost-mldsa.crt -key localhost-mldsa.key \
-trace -port 4433
Use curl to test:
curl -k -v https://localhost:4433/
you will get:
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ml-dsa-65
If you try firefox you will get an error:
Error code: SSL_ERROR_NO_CYPHER_OVERLAP
that is expected as Firefox doesn't support the key/cert openssl is using.
Create a RSA key/cert using openssl:
openssl req \
-x509 \
-keyout localhost.key \
-subj /CN=localhost \
-addext subjectAltName=DNS:localhost \
-days 30 \
-nodes \
-out localhost.crt
Start openssl s_server using the 2 keys and 2 certificates:
openssl s_server \
-cert localhost-mldsa.crt -key localhost-mldsa.key \
-dcert localhost.crt -dkey localhost.key \
-trace -port 4433
Check that curl is working and using the PQC key/cert pair:
curl -k -v https://localhost:4433/
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ml-dsa-65
Try Firefox now, the certificate is self-signed but now Firefox accepts it.