Code Lab (runnable)
Copy-paste PQC recipes you can run today. The OpenSSL examples below were executed on OpenSSL 3.6.1 (native ML-KEM / ML-DSA / SLH-DSA, available since 3.5) and the outputs shown are the real results — note how the sizes match the FIPS parameter sets documented elsewhere on this site.
openssl version). The liboqs
Python section additionally needs liboqs-python. Nothing here touches production keys.
0. Confirm PQC support
openssl version
openssl list -public-key-algorithms | grep -Ei 'ML-DSA|SLH-DSA|ML-KEM'
openssl list -kem-algorithms | grep -i mlkem
openssl list -signature-algorithms | grep -Ei 'ML-DSA|SLH-DSA'
OpenSSL 3.6.1 27 Jan 2026
{ ... id-alg-ml-kem-768, ML-KEM-768, MLKEM768 } @ default
X25519MLKEM768 @ default # hybrid group used by TLS 1.3
{ ... id-ml-dsa-65, ML-DSA-65, MLDSA65 } @ default
{ ... id-slh-dsa-sha2-128s, SLH-DSA-SHA2-128s } @ default
Different distributions, providers, and builds may display different aliases; rely on your own openssl list output as the source of truth.
1. ML-KEM-768 — key encapsulation
Establish a shared secret the post-quantum way: the recipient publishes an encapsulation key; the sender encapsulates a fresh 32-byte secret to it; the recipient decapsulates the same secret.
# recipient: keypair
openssl genpkey -algorithm ML-KEM-768 -out mlkem.key
openssl pkey -in mlkem.key -pubout -out mlkem.pub
# sender: encapsulate a shared secret to the public key
openssl pkeyutl -encap -inkey mlkem.pub -pubin -out ct.bin -secret ss_sender.bin
# recipient: decapsulate to recover the same secret
openssl pkeyutl -decap -inkey mlkem.key -in ct.bin -secret ss_recv.bin
cmp -s ss_sender.bin ss_recv.bin && echo "shared secrets MATCH"
ciphertext: 1088 bytes, shared secret: 32 bytes
shared secrets MATCH # ML-KEM-768 sizes per FIPS 203
2. ML-DSA-65 — sign & verify
openssl genpkey -algorithm ML-DSA-65 -out mldsa.key
openssl pkey -in mldsa.key -pubout -out mldsa.pub
echo "hello pqc world" > msg.txt
openssl pkeyutl -sign -inkey mldsa.key -rawin -in msg.txt -out msg.sig
openssl pkeyutl -verify -pubin -inkey mldsa.pub -rawin -in msg.txt -sigfile msg.sig
3309 byte signature # ML-DSA-65 per FIPS 204
Signature Verified Successfully
3. SLH-DSA — the conservative, large-signature option
openssl genpkey -algorithm SLH-DSA-SHA2-128s -out slh.key
echo hi > m.txt
openssl pkeyutl -sign -inkey slh.key -rawin -in m.txt -out slh.sig
wc -c slh.sig
7856 slh.sig # SLH-DSA-128s signature per FIPS 205 — ~2.4x larger than ML-DSA-65 at this parameter set; other SLH-DSA parameter sets can be far larger,
# and signing is much slower. Use where hash-only assurance matters most.
4. Hybrid TLS 1.3 in the wild
Force the post-quantum hybrid group and confirm a real server negotiates it (Cloudflare supports it):
echo | openssl s_client -groups X25519MLKEM768 -connect cloudflare.com:443 \
-servername cloudflare.com 2>/dev/null | grep -iE 'Negotiated TLS1.3 group|Protocol'
Negotiated TLS1.3 group: X25519MLKEM768
Protocol: TLSv1.3
Support status at real public endpoints varies with server configuration and middleboxes; a failed negotiation does not necessarily mean OpenSSL lacks support — the site may simply not offer that group, or a downgrading/intercepting device may sit on the path.
To inventory your own endpoints, use scan-tls.sh from the Discovery page.
5. A self-signed ML-DSA certificate
openssl req -x509 -new -newkey ML-DSA-65 -keyout ca.key -out ca.crt \
-days 365 -nodes -subj "/CN=pqc-demo"
openssl x509 -in ca.crt -noout -text | grep -i 'Signature Algorithm' | head -1
Signature Algorithm: ML-DSA-65
This certificate is fine for local experiments; many clients, proxies, load balancers, and certificate-handling tools may still not accept an ML-DSA certificate chain. Test end-to-end before production.
6. liboqs (Python) — algorithm-level API
For experimenting across the full algorithm set (including HQC, Falcon, McEliece) the Open Quantum Safe binding is convenient. How liboqs-python installs varies by platform and version; if the pip install fails, follow the current liboqs-python README. Some environments need CMake, a compiler, and the liboqs C library installed first. The pip command below is just one possible install path, shown for illustration.
pip install liboqs-python
import oqs
with oqs.KeyEncapsulation("ML-KEM-768") as kem:
pk = kem.generate_keypair()
ct, ss_sender = kem.encap_secret(pk)
ss_recv = kem.decap_secret(ct)
assert ss_sender == ss_recv
with oqs.Signature("ML-DSA-65") as sig:
pk = sig.generate_keypair()
s = sig.sign(b"hello pqc world")
assert sig.verify(b"hello pqc world", s, pk)
print(oqs.get_enabled_kem_mechanisms()[:5])
print(oqs.get_enabled_sig_mechanisms()[:5])
Standards & references
- OpenSSL — 3.5+ ships native ML-KEM/ML-DSA/SLH-DSA; see OpenSSL Provider.
- Open Quantum Safe — liboqs & bindings; see liboqs.
- Sizes verified here match FIPS 203 / 204 / 205; full table in Comparison.
- Resources — full standards register
实操实验室
可直接复制运行的 PQC 实操配方。下面的 OpenSSL 示例在 OpenSSL 3.6.1(自 3.5 起原生支持 ML-KEM / ML-DSA / SLH-DSA)上实跑,所示输出为真实结果——注意尺寸与本站其他页给出的 FIPS 参数集完全吻合。
openssl version)。liboqs 的 Python 部分另需
liboqs-python。本页不涉及任何生产密钥。
0 确认 PQC 支持
openssl version
openssl list -public-key-algorithms | grep -Ei 'ML-DSA|SLH-DSA|ML-KEM'
openssl list -kem-algorithms | grep -i mlkem
openssl list -signature-algorithms | grep -Ei 'ML-DSA|SLH-DSA'
OpenSSL 3.6.1 27 Jan 2026
{ ... id-alg-ml-kem-768, ML-KEM-768, MLKEM768 } @ default
X25519MLKEM768 @ default # TLS 1.3 使用的混合组
{ ... id-ml-dsa-65, ML-DSA-65, MLDSA65 } @ default
{ ... id-slh-dsa-sha2-128s, SLH-DSA-SHA2-128s } @ default
不同发行版 / provider / 构建可能显示不同别名,应以本机 openssl list 输出为准。
1 ML-KEM-768 密钥封装
用后量子方式协商共享密钥:接收方公布封装公钥;发送方向其封装一个全新的 32 字节密钥;接收方解封装得到相同密钥。
# 接收方:生成密钥对
openssl genpkey -algorithm ML-KEM-768 -out mlkem.key
openssl pkey -in mlkem.key -pubout -out mlkem.pub
# 发送方:用公钥封装共享密钥
openssl pkeyutl -encap -inkey mlkem.pub -pubin -out ct.bin -secret ss_sender.bin
# 接收方:解封装恢复出相同密钥
openssl pkeyutl -decap -inkey mlkem.key -in ct.bin -secret ss_recv.bin
cmp -s ss_sender.bin ss_recv.bin && echo "shared secrets MATCH"
ciphertext: 1088 bytes, shared secret: 32 bytes
shared secrets MATCH # ML-KEM-768 尺寸符合 FIPS 203
2 ML-DSA-65 签名与验签
openssl genpkey -algorithm ML-DSA-65 -out mldsa.key
openssl pkey -in mldsa.key -pubout -out mldsa.pub
echo "hello pqc world" > msg.txt
openssl pkeyutl -sign -inkey mldsa.key -rawin -in msg.txt -out msg.sig
openssl pkeyutl -verify -pubin -inkey mldsa.pub -rawin -in msg.txt -sigfile msg.sig
3309 byte signature # ML-DSA-65 符合 FIPS 204
Signature Verified Successfully
3 SLH-DSA 保守的大签名方案
openssl genpkey -algorithm SLH-DSA-SHA2-128s -out slh.key
echo hi > m.txt
openssl pkeyutl -sign -inkey slh.key -rawin -in m.txt -out slh.sig
wc -c slh.sig
7856 slh.sig # SLH-DSA-128s 签名符合 FIPS 205——在该参数集下约为 ML-DSA-65 的 2.4 倍;其他 SLH-DSA 参数集可大得多,
# 且签名慢得多。适用于最看重「仅依赖哈希」假设的场景。
4 真实世界中的混合 TLS 1.3
强制使用后量子混合组,并确认真实服务器会协商它(Cloudflare 已支持):
echo | openssl s_client -groups X25519MLKEM768 -connect cloudflare.com:443 \
-servername cloudflare.com 2>/dev/null | grep -iE 'Negotiated TLS1.3 group|Protocol'
Negotiated TLS1.3 group: X25519MLKEM768
Protocol: TLSv1.3
真实公网端点的支持状态会随服务端配置和中间设备变化;若协商失败,不一定是 OpenSSL 不支持,也可能是该站点暂未提供该组或路径上存在降级/拦截设备。
盘点自有端点请用资产发现页的 scan-tls.sh。
5 自签名 ML-DSA 证书
openssl req -x509 -new -newkey ML-DSA-65 -keyout ca.key -out ca.crt \
-days 365 -nodes -subj "/CN=pqc-demo"
openssl x509 -in ca.crt -noout -text | grep -i 'Signature Algorithm' | head -1
Signature Algorithm: ML-DSA-65
这张证书适合本地实验;大量客户端、代理、负载均衡器和证书处理工具仍可能无法接受 ML-DSA 证书链。生产前必须端到端测试。
6 liboqs Python 算法级 API
若要遍历完整算法集(含 HQC、Falcon、McEliece),Open Quantum Safe 的绑定很方便。liboqs-python 的安装方式随平台和版本变化;若 pip 安装失败,应以当前 liboqs-python README 为准。部分环境需要先安装 CMake、编译器和 liboqs C 库。下面的 pip 命令只是其中一种可能的安装路径,仅作示意。
pip install liboqs-python
import oqs
with oqs.KeyEncapsulation("ML-KEM-768") as kem:
pk = kem.generate_keypair()
ct, ss_sender = kem.encap_secret(pk)
ss_recv = kem.decap_secret(ct)
assert ss_sender == ss_recv
with oqs.Signature("ML-DSA-65") as sig:
pk = sig.generate_keypair()
s = sig.sign(b"hello pqc world")
assert sig.verify(b"hello pqc world", s, pk)
print(oqs.get_enabled_kem_mechanisms()[:5])
print(oqs.get_enabled_sig_mechanisms()[:5])
标准与参考
- OpenSSL——3.5+ 原生支持 ML-KEM/ML-DSA/SLH-DSA;见 OpenSSL 提供者。
- Open Quantum Safe——liboqs 与各语言绑定;见 liboqs。
- 本页实测尺寸与 FIPS 203 / 204 / 205 一致;完整表见 算法对比。
- 资源链接——完整标准登记册