Java 平台与后量子密码:从威胁模型到 JDK 交付路径#
大规模量子计算机若达到密码学相关规模(Cryptographically Relevant Quantum Computer,CRQC),Shor 算法可在多项式时间内分解整数、求解离散对数,从而瓦解今日 TLS 与 PKI 所依赖的 RSA、有限域 Diffie-Hellman 与椭圆曲线体系。对称算法不受 Shor 直接影响;Grover 算法对对称密钥搜索仅有平方级加速,业界常据此建议在高价值场景倾向 AES-256——此为常见风险判断,并非 JDK 默认强制行为。
对 Java 服务端而言,真正紧迫的往往不是「等量子机上市再改一行配置」,而是先采集、后解密(harvest now, decrypt later,亦称 HNDL):攻击者今日即可存档握手与密文,待日后 CRQC 可用再还原会话密钥。JEP 496 与 JEP 527 的动机段落均采用类似表述。相对地,证书与 JAR 签名更多关系身份伪造与供应链信任,轮换节奏与「历史流量机密性」不同;将密钥交换优先于签名升级属于风险建模(演讲者观点),NIST/JEP 并未用同一句式规定全局排期——企业仍须并行规划 ML-DSA 等签名迁移。
下文按「威胁 → 标准命名 → 平台 API → 协议落地 → 运维」组织,面向已有 JCA/JSSE 经验的工程师。每个技术块尽量交代:为何需要、机制与约束、最小可运行示例、常见误区。JDK 版本以 OpenJDK JEP 与发行说明为准;幻灯片提到的 ML-KEM/ML-DSA backport 至 JDK 21/17(2026 下半年)未在对应 JEP 正文核实,生产排期应跟踪 Oracle 更新公告。
架构团队宜在合规台账中同时记录三列:FIPS 算法名、IANA TLS group 名、最低 JDK 版本——三者任一错位,都会出现「算法库已升级、线上握手仍 ECDHE」的假象。
TLS 握手里的脆弱环节#
为何:企业机密流量、医疗与金融报文、云 API 调用大多走 TLS。威胁模型若只问「CRQC 何时商用」,会低估对手今日抓包、明日解密的能力;这与签名证书「到期轮换」的时间尺度不同。
机制:RFC 8446 将 TLS 1.3 分为密钥交换、认证(数字签名)与记录层对称加密三层。前两者依赖传统非对称原语;记录层在握手完成后由协商出的对称密钥保护,不受 Shor 直接威胁,但在长期日志场景下,一旦握手阶段的密钥交换被攻破,历史 Application Data 的机密性随之丧失。认证失败导致的是伪造身份与中间人风险,与 HNDL 针对过去机密性的攻击面应分开评估。

图:A CRQC Will Break Internet Communications Using Traditional Asymmetric Cryptography — TLS 1.3 握手的 Key Exch 与 Authn 依赖传统非对称密码。
机制与约束:Shor 作用于公钥体系,不替代对 TLS 实现缺陷、弱套件或密钥管理的防护。探测对端是否协商后量子混合组可用 OpenSSL s_client -groups(取决于对端与本机 OpenSSL 版本,非 JDK 行为)。
最小观测(JDK 应用通常无需改代码即可在 JDK 27 受益混合组,见后文):
openssl s_client -connect api.example.com:443 -tls1_3 -groups X25519MLKEM768 </dev/null 2>/dev/null \
| grep -E 'Protocol|Cipher|Named Group'
常见误区:把「对称套件仍安全」等同于「整条 TLS 链路可推迟迁移」;忽略已落盘的握手与密文档案。另一误区是把 HNDL 当作唯一优先级而无限期推迟 ML-DSA 证书与 JAR 签名升级——联邦与行业指引(如 CNSA 2.0 方向)仍要求签名体系迁移,只是紧迫性场景不同。
NIST 标准与工程命名对齐#
为何:采购合同、渗透测试报告与 JDK 发行说明使用不同命名空间;不对齐会导致验收失败或错误选型(例如把竞赛版 Kyber 与 FIPS ML-KEM 混为一谈)。
机制:NIST 后量子密码项目 自 2016 年征集,2022 年公布首批入选算法,2024 年 8 月发布 FIPS 203 ML-KEM、FIPS 204 ML-DSA、FIPS 205 SLH-DSA。竞赛昵称 Kyber、Dilithium 与 FIPS 定稿名不保证与早期实现互通——JEP 496 明确 ML-KEM 与 Kyber 不互通,JEP 497 对 ML-DSA 与 Dilithium 同理。Falcon 对应进行中的 FN-DSA(FIPS 206 尚无 final 页面);HQC 于 2025 年 3 月入选标准化(NIST 项目页)。

图:NIST PQC Standardization — December 2016 Call for Proposals 至 August 2024 Final FIPS Published。
| 竞赛/旧称 | FIPS | JDK 族名(示例) |
|---|---|---|
| Kyber | 203 | ML-KEM、ML-KEM-768 |
| Dilithium | 204 | ML-DSA、ML-DSA-65 |
| SPHINCS+ | 205 | SLH-DSA(JDK 内置范围本篇不展开) |
怎么做:在架构决策记录(ADR)或基础设施即代码中固定 FIPS 编号,避免口头昵称漂移:
crypto_standards:
kem: { name: ML-KEM, fips: "203", jca: ML-KEM-768 }
signature: { name: ML-DSA, fips: "204", jca: ML-DSA-65 }
常见误区:采购清单写「Kyber」,验收脚本却调 ML-KEM 参数集,互操作失败却被归咎于 JDK bug。另一误区是假设 FIPS 206(FN-DSA)已发布——截至常见核实路径,final 页面可能仍不可用,应写「标准化进行中」。
混合方案:过渡期的安全叙事#
为何:纯后量子算法仍在持续密码分析中;纯经典算法则无法抵御 CRQC 下的 HNDL。混合是在已知风险与新兴算法审慎之间的工程折中。
机制:过渡期普遍采用经典 + 后量子组合:只要组合中有一侧在可预见未来内未被攻破,混合密钥交换即可维持「可辩护」的安全主张。JEP 527 原文:secure as long as one of the algorithms remains unbroken。NIST FIPS 覆盖单算法语义;TLS named group 的组合由 IETF 定义(如 draft-ietf-tls-hybrid-design),IANA TLS Supported Groups 已登记 X25519MLKEM768 等。

怎么做:产品层 ADR 可写明默认偏好 X25519MLKEM768,并与 JDK 27 默认策略对齐;合规侧说明「NIST FIPS 覆盖单算法,TLS 组合由 IETF 定义」,避免审计方要求 NIST 出具「混合套件证书」——该组合通常不在 FIPS 单算法认证范围内。
常见误区:认为「实验室已测 ML-KEM-768」即生产 TLS 已协商混合组;JDK 24 交付 ML-KEM API 时 JEP 496 Non-Goals 明确尚未在 javax.net.ssl 支持 ML-KEM TLS——PQ 混合 TLS 在 JDK 27(JEP 527)。将「默认混合」当作无需变更管理:IETF 草案仍可能调整 wire format,须预留回归窗口。
JCA 分层与路线图门禁#
为何:Java 长期通过 Provider 抽象屏蔽硬件与 FIPS 模块差异;PQC 仍走同一模型,否则 HSM、云 KMS 与 SunJCE 将各自为政。
机制:应用通过 JCA 的 Signature、KeyPairGenerator、Cipher 等引擎类编程,由 Provider(SunJCE、第三方 HSM)落地。JDK 21 起新增 KEM;JDK 25 定稿 KDF(JDK 24 预览 JEP 478)。弱算法淘汰节奏见 Oracle Java Cryptographic Roadmap(页面可随时更新,CI 应绑定具体 JDK 版本的 Release Notes)。

图:Building the PQC Foundation — JCA/JCE 中 KEM、KDF 标注 New,对应 ML-KEM、HKDF 等实现。
怎么做:升级流水线应同时跑三类检查——(1) java.security 禁用算法是否与路线图一致;(2) 标准算法名是否包含 ML-KEM/ML-DSA;(3) 若使用 Bouncy Castle 等第三方 Provider,其 PQ 实现是否与 SunJCE 参数集一致。
常见误区:只盯 JDK 大版本号,忽略 java.security 属性与 Release Notes 的增量变更;在 JDK 24 启用 ML-DSA API 却用 JDK 21 的 jarsigner 做发布门禁。
KEM API:为何 KeyAgreement 不够#
为何:TLS 1.3、HPKE 等现代协议以 KEM 为中心交换对称密钥;用 RSA 加密随机 AES 密钥或滥用 KeyAgreement 表达 encapsulation,既难审计也易踩侧信道与语义错误。
机制:密钥封装(KEM)在不安全信道上封装对称密钥,语义上优于「随机对称密钥 + RSA 公钥加密」的旧模式。JEP 452 指出既有 KeyAgreement、KeyGenerator、Cipher 不足以表达 KEM;故引入 javax.crypto.KEM 及 KEM.Encapsulator / KEM.Decapsulator。

图:KEM API JDK 21 — None of existing APIs (KeyAgreement, KeyGenerator, Cipher) were sufficient;Two main classes: KEM.Encapsulator and KEM.Decapsulator。

图:JEP 452: Key Encapsulation Mechanism API KEM API Owner Weijun Wang Type Feature JDK 21 Scope SE Status Closed/Delivered Release 21。
import javax.crypto.KEM;
import javax.crypto.SecretKey;
KEM kem = KEM.getInstance("ML-KEM");
KEM.Encapsulator enc = kem.newEncapsulator(peerPublicKey);
KEM.Encapsulated out = enc.encapsulate();
byte[] kemMessage = out.encapsulation();
SecretKey shared = out.key();
常见误区:在 JDK 21 上调用 KEM.getInstance("ML-KEM")——算法实现随 JEP 496 在 JDK 24 交付。幻灯片称 API backport 至 JDK 17:JEP 452 正文未记载,若需写入生产基线应查 Oracle 商业更新说明或标为演讲者表述。
ML-KEM:参数集、PKI 与封装方向#
为何:HNDL 场景下需要可互操作的 lattice KEM;FIPS 203 定稿后 JDK 以 JCA 标准名交付,便于与 NIST 测试向量及 TLS 草案对齐。
机制:JEP 496(JDK 24,security-libs/javax.crypto)实现 FIPS 203,参数集 ML-KEM-512、ML-KEM-768、ML-KEM-1024,默认 ML-KEM-768。keytool 可生成 ML-KEM 密钥对与证书,但 ML-KEM 不是签名算法,证书须由 RSA 或 ML-DSA 等签发——JEP 原文:cannot be used to sign the certificate containing the ML-KEM public key。

图:JEP 496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism ML-KEM … mechanism specified in FIPS 203。
在 draft-ietf-tls-ecdhe-mlkem 语义下,客户端 key_share 携带封装公钥,服务端返回密文;与 API 层 sender encapsulate、receiver decapsulate 角色一致。
keytool -genkeypair -alias pq-ca -keyalg ML-DSA -groupname ML-DSA-65 \
-dname "CN=PQ CA" -keystore ks -storepass changeit -ext bc:critical=ca:true
keytool -genkeypair -alias mlkem-ee -keyalg ML-KEM -groupname ML-KEM-768 \
-signer pq-ca -keystore ks -storepass changeit
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM");
KeyPair clientKp = kpg.generateKeyPair();
KEM kem = KEM.getInstance("ML-KEM");
KEM.Decapsulator dec = kem.newDecapsulator(clientKp.getPrivate());
// SecretKey shared = dec.decapsulate(kemMsgFromServer);
参数集选择:ML-KEM-512 体积更小、ML-KEM-1024 安全余量更高;通用默认 ML-KEM-768 与 NIST Level 3 叙事及 TLS 混合组中的 768 实例一致。NamedParameterSpec 常量 ML_KEM_768 等可在显式 initialize 时使用。
常见误区:用 ML-KEM 自签证书;或假设 JDK 24 默认 HTTPS 已启用 PQ——须 JDK 27 + 对端支持混合组。把 API 演示中的「客户端 decapsulate」硬编码到所有协议角色——在纯 KEM 消息协议中角色可能相反,须以协议规范为准。
ML-DSA:签名、JAR 与版本分叉#
为何:供应链签名、代码分发与 TLS 证书链长期依赖 RSA/ECDSA;CRQC 下需可验证的后量子签名,且与 FIPS 204 测试向量一致。
机制:JEP 497(JDK 24,java.security)交付 FIPS 204,参数集 ML-DSA-44、ML-DSA-65、ML-DSA-87,默认 ML-DSA-65。JEP 497 的 Non-Goals 包含 JDK 24 内对 JAR/TLS 的 ML-DSA 支持;jarsigner 对 ML-DSA 的签名与验证在 JDK 26 发行说明中交付(RFC 9882)。

图:JEP 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm ML-DSA … lattice-based signature algorithm specified in FIPS 204。
jarsigner -sigalg ML-DSA-65 -keystore ks -storepass changeit test.jar ML-DSA \
-signedjar signed.jar
jarsigner -verify -verbose signed.jar
import java.security.*;
import java.security.spec.NamedParameterSpec;
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA");
kpg.initialize(new NamedParameterSpec("ML-DSA-65"));
KeyPair kp = kpg.generateKeyPair();
Signature sig = Signature.getInstance("ML-DSA");
sig.initSign(kp.getPrivate());
sig.update(messageBytes);
byte[] signatureBytes = sig.sign();
有状态哈希签名 HSS/LMS(RFC 8554)自 JDK 21 起内置验证路径;生产签名与 keytool 生成有状态密钥对通常仍需第三方 Provider——误把「能 jarsigner -verify LMS JAR」当作产线签名能力会导致密钥重用类事故。
常见误区:在 JDK 24 CI 上要求 ML-DSA 签名 JAR 通过,却未升级到 JDK 26。
KDF 与 HKDF:KEM 输出到会话密钥#
为何:KEM 输出的是短共享秘密,协议通常还需 HKDF 派生多把密钥(客户端/服务端写密钥、IV、完成标签等)。SecretKeyFactory 面向 PBKDF2 等密码存储场景,无法表达 extract-then-expand 语义。
机制:javax.crypto.KDF 补齐现代 KDF 抽象;内置 HKDF(HKDF-SHA256/384/512),用于 HPKE、TLS 1.3 混合交换等。JEP 510 称计划实现 Argon2,截至 JEP 正文尚未作为内置算法交付。

图:JEP 510: Key Derivation Function API KDF API Owner Kevin Driver … Previewed in JEP 478 (JDK 24) and finalized in。
import javax.crypto.KDF;
import javax.crypto.spec.HKDFParameterSpec;
KDF hkdf = KDF.getInstance("HKDF-SHA384");
// HKDFParameterSpec:extract 的 IKM 可为 KEM 输出;thenExpand 派生 AES 等
// SecretKey aesKey = hkdf.deriveKey("AES", spec);
JEP 510 明确 TLS 1.3(含混合密钥交换)是 KDF API 的目标用例之一;与 JEP 527 在路线图上的耦合意味着:底层 KDF 定稿(25)早于或并行于 JSSE 混合 TLS(27),应用开发者多数情况下仍不直接调用 HKDF,但自定义协议栈(如 gRPC 实验性 PQ 通道)会用到。
常见误区:在 JDK 24 生产代码依赖定稿 KDF API——定稿在 JDK 25。在预览 API 上 @PreviewFeature 未移除就发布库构件。误以为 Argon2 已内置——JEP 仅表达意图,须跟踪后续 JEP。
HPKE:KEM + KDF + AEAD 三元组#
为何:应用常需「用接收方公钥加密任意长度明文」;在 KEM 层之上用 AEAD 封装是 RFC 9180 的标准做法,避免自行拼接 KEM 输出与对称加密。
机制:RFC 9180 将 HPKE 定义为 KEM、KDF、AEAD 的组合;JDK 26 通过 Cipher.getInstance("HPKE") 与 HPKEParameterSpec 暴露。RFC 9180 标准化 profile 以 DHKEM(如 DHKEM(X25519, HKDF-SHA256))为主,未定义 ML-KEM 的 HPKE code point;JDK 26 初版因而以经典套件为主,PQC profile 待 IETF 定稿 RFC 后再扩展——演讲者/路线图表述 + RFC 范围推断,非单独 JEP 页面在本次可引用条文。

图:Hybrid Public Key Encryption (HPKE) JDK 26 — Modern encryption scheme … defined in RFC 9180。
import javax.crypto.Cipher;
// Cipher hpke = Cipher.getInstance("HPKE");
// hpke.init(Cipher.ENCRYPT_MODE, recipientPublicKey, hpkeParameterSpec);
常见误区:无 HPKEParameterSpec 即调用 getInstance("HPKE");在 JDK 26 期望 ML-KEM HPKE profile——RFC 9180 当前标准化的是 DHKEM 族,PQC profile 须等 IETF 增补。
TLS 1.3 后量子混合密钥交换(JDK 27)#
为何:这是多数 Java 微服务零业务代码改动即可缓解 HNDL 的主路径:握手在 JSSE 内完成,无需应用直接调用 KEM.encapsulate。
机制:JEP 527 将混合密钥交换整合进 javax.net.ssl TLS 1.3:默认在客户端 offer 列表首位启用 X25519MLKEM768;另支持 SecP256r1MLKEM768、SecP384r1MLKEM1024(默认未启用后两者)。未手动限制 named groups 时,多数应用 without change to existing code 即可获得混合保护;自定义顺序可用 SSLParameters.setNamedGroups 或系统属性 jdk.tls.namedGroups。

图:Post-Quantum Hybrid Key Exchange for TLS 1.3 JDK 27 Combines classical and post-quantum key exchange algorithms Protects against HNDL。
jdk.tls.namedGroups=X25519MLKEM768,SecP256r1MLKEM768,SecP384r1MLKEM1024
import javax.net.ssl.*;
SSLParameters p = sslSocket.getSSLParameters();
p.setNamedGroups(new String[] { "SecP256r1MLKEM768", "X25519MLKEM768" });
sslSocket.setSSLParameters(p);

风险(JEP 527):IETF 规范仍为 draft,RFC 定稿后 JDK 行为可能调整。JEP Non-Goal 包含纯 ML-KEM TLS(非混合)。
自定义 SSLEngine、Netty SslContext 或显式 jdk.tls.namedGroups 时,应做互操作矩阵:JDK 27 客户端对 OpenSSL 3.5+、BoringSSL 等 peer 的混合组支持不一。FIPS 140 模块认证边界:混合 TLS 是否落入模块安全策略须问 HSM/JDK FIPS 供应商,超出 OpenJDK 通用文档范围。
常见误区:仅升级 JDK 27 而未确认负载均衡、API 网关、旧版 Android/浏览器是否支持混合组,导致静默回退经典 ECDHE。手动把 jdk.tls.namedGroups 设为仅 X25519 以「提速」,实则关闭 PQ 保护。
运维:可观测性与性能边界#
为何:车队成百上千 JVM 时,需要证明「未偷偷放宽 TLS」而非抽样一台手工 openssl s_client。
机制:OpenJDK 提供 JFR 事件 jdk.TLSHandshake(字段含 protocolVersion、cipherSuite、certificateId 等)。该事件不包含 negotiated named group——仅凭 JFR 难以证明混合组已生效;可结合 JDK 26+ 的 java -XshowSettings:security:tls、抓包或供应商扩展事件。JEP 527 / 本场材料未提供 PQ TLS 握手量化性能数据,容量规划应引用独立基准,不得编造延迟或吞吐数字。
java -XX:StartFlightRecording=duration=60s,filename=pq-tls.jfr -jar app.jar
java -XshowSettings:security:tls -version
对需要 named group 证据的环境,可在预发用 Wireshark 解析 supported_groups / key_share,或编写一次性探针连接已知支持混合组的测试端点。Q&A 中提到的 JFR 观察 TLS 宜理解为协议版本、套件与证书等字段;若演讲暗示可一眼看出 X25519MLKEM768,与当前 TLSHandshakeEvent 字段集可能不一致——以源码为准。
常见误区:用本场未给出的 handshake 延迟数字做容量规划;把 Grover 威胁写成「必须立刻禁用 AES-128-GCM」——须结合协议互操作与性能预算逐项决策。
迁移检查清单(工程视角)#
- 运行时:计划 JDK 27(或带 JEP 527 的 EA)用于对外 TLS;JDK 26+ 用于 ML-DSA JAR 签名流水线;JDK 24+ 用于生成 ML-KEM/ML-DSA 密钥材料。
- 边缘与客户端:梳理 L7/L4 终止代理、Service Mesh、mTLS 双向认证对 named group 的影响。
- PKI:区分 KEM 证书载体与签发算法;CA 先具备 ML-DSA(或过渡期 RSA)签发能力。
- 供应链:
jarsigner -sigalg ML-DSA-65与依赖方 JDK 验证版本对齐。 - 合规台账:FIPS 203/204 编号 + IANA group 名 + JDK 版本三列绑定。
- 观测:JFR +
security:tls设置 + 抽样抓包,避免单一信号误判。
能力叠代速查#
| 能力 | JDK 版本 | 依据 |
|---|---|---|
KEM API | 21 | JEP 452 |
| ML-KEM / ML-DSA 算法 | 24 | JEP 496 / 497 |
KDF 定稿 / HKDF | 25 | JEP 510 |
ML-DSA jarsigner | 26 | JDK 26 RN |
HPKE Cipher | 26 | JDK 26 RN |
| PQ 混合 TLS | 27 | JEP 527 |
早期访问构建见 jdk.java.net/27。PEM API、Argon2、TLS 证书压缩、LMS RFC 9858、jlink 安全插件等路线图条目须逐条查 JEP 当前状态,未在本篇核实。



