Spring Boot中的后量子密码学:本迭代可落地的四种模式
核心要点
- 如果你已经在使用 JDK 24,就可以直接通过标准 Java 加密扩展(JCE)API 使用基于模格的密钥封装机制(ML-KEM)和基于模格的数字签名算法(ML-DSA),无需额外引入库。你原本可能就在规划的 JDK 升级(JDK 24),也会一并打通整个后量子密码学(PQC)迁移之路。
- 现在正有人保存你用 RSA 封装的 TLS 会话,打算以后解密。因此,今天在你的服务之间流动的任何客户社会安全号码(SSN)、交易记录和“了解你的客户”(KYC)文档,都已经处于风险之中。等待云服务商提供 PQC TLS,并不是一个迁移计划。
- 用 Kyber 密钥加密数据库字段并不难;真正的难点在于确保该密钥不会驻留在 JVM 堆中。因为一次服务器重启或一次堆转储,就会让数据库中所有加密行无法读取。在部署到生产环境之前,必须先集成密钥管理服务(KMS)或 HashiCorp Vault。
- 核心银行、欺诈检测和监管报告流水线中使用的 OAuth2 令牌和服务账户凭据,通常有效期长达数月甚至数年,因此它们比短期客户会话令牌更需要优先进行 PQC 迁移。
- 从生命周期最长的数据开始 PQC 迁移,而不是从你最熟悉的授权层开始。因为今天用 RSA 签署的贷款协议和 KYC 记录,到 2035 年左右签名将可以被伪造,届时你无法对已归档的文档进行追溯重签。
背景
2024 年 8 月,NIST 最终确定了 FIPS 203 和 FIPS 204 规范之后,受监管行业中大多数工程团队开始问同一个问题:“我们到底该从哪里开始?”显而易见的答案是“切换到 PQC TLS”,但这一能力仍在云服务商中逐步推出,大多数团队今天还无法启用。与此同时,真正的风险已经在发生:攻击者现在就在截获并存储你的加密服务间流量,以便将来量子硬件成熟后解密。
考虑一个典型的零售银行微服务平台,它基于 Spring Boot 构建:一个交易服务(Transaction Service)向核心银行服务(Core Banking Service)发送支付指令,同时将客户个人身份信息(PII)和 KYC 数据写入 PostgreSQL。
相关赞助商
- 现代移动应用安全中实时威胁监控与分析的必要性
- 摩根士丹利如何利用自动化重构扩展软件现代化
- Akka 推出面向自主、实时与边缘 AI 系统的 Agentic 平台
- 工程领导者 AI 手册:从 AI 实验到生产系统
- AI Agent 群体模式(InfoQ 网络研讨会)—— 立即点播观看
此外,该平台还会有贷款协议、开户文件归档在 Amazon S3 中,以及接入 SWIFT 和 ACH 连接器的监管报告流水线所依赖的 OAuth2 服务账户令牌。这种拓扑对于中大型银行来说非常典型。问题是,对于其中每一部分,“抗量子安全”到底意味着什么。答案因部分而异。
本文针对该拓扑给出了四个具体模式,使用的是名为 PqcStarterLib 的 Spring Boot PQC 库。它把 Bouncy Castle 的 PQC Provider 封装在三个自动配置的 Bean 后面。这些模式涵盖:银行内部服务之间的负载加密;在 Jakarta Persistence 写入数据库之前对 PII 和 KYC 字段进行字段级加密;使用 Dilithium 对贷款协议和审计记录进行长期文档签名;以及为核心银行和监管流水线中使用的服务账户提供抗量子 OAuth2 令牌签名。每个模式都附带可运行的 Spring Boot 代码,并诚实指出是什么阻碍了它直接进入生产环境。
零售银行之所以是“现在收集,以后解密”(HNDL)特别有吸引力的目标,是因为银行数据的保质期很长。今天被盗的客户 SSN 在 2035 年仍然有用。一份贷款协议,其 RSA 签名在十年后会被伪造,这是一种无法追溯补救的法律责任。本文中的模式就是围绕这一现实设计的。
威胁的通俗解释
RSA 和 ECDSA 之所以有效,是因为分解大整数和求解离散对数对于经典计算机来说是难题。而运行 Shor 算法 的量子计算机可以在多项式时间内解决这两个问题。IBM、谷歌以及多个国家实验室目前已经拥有可工作的量子处理器,只是还没有达到破解 RSA-2048 所需的规模。多数专家认为这一临界点大约在 2030 到 2035 年之间。
等不起的部分是 HNDL。攻击者现在就在拦截并存储加密的 TLS 流量。建立 TLS 会话时使用的 RSA 密钥交换会与密文一起被记录下来。一旦存在足够强大的量子计算机,他们就会回头解密。对零售银行来说,受影响范围包括服务之间流动的客户 KYC 数据、交易记录、银行间结算消息,以及任何通过线路传输且需要多年保持机密的文档。
另一个等不起的部分是长期有效的签名文档。如果一份贷款协议今天用 RSA 签署,并且需要在 2036 年仍然具备法律效力,那么你面临的问题在事后无法修复。银行会将贷款协议、开户合同和审计跟踪归档七到三十年不等,具体取决于监管辖区。你无法追溯性地重新签署已归档的文档。
短生命周期数据风险较低。客户会话令牌 15 分钟过期,即使使用 RSA 签名密钥也基本没问题,因为它在任何人破解之前就已经没有价值了。但用于核心银行集成、欺诈检测流水线和 SWIFT 连接器、且有效期为数月乃至更长时间的 OAuth2 服务账户令牌,就另当别论了。这正是 HNDL 攻击的目标。
PqcStarterLib 为 Spring Boot 带来了什么
PqcStarterLib 基于 Bouncy Castle 对 FIPS 203 和 FIPS 204 的实现构建。它暴露了三个在启动时自动配置的 Spring Bean:
PqcEncryptionService提供混合加密:使用 Kyber KEM 建立一次性共享密钥,然后使用 AES-256-GCM 加密实际负载。任何需要保密的服务间消息体或数据库字段,都可以使用此服务。PqcSignatureService使用 CRYSTALS-Dilithium 提供签名和验证。可用于贷款协议、KYC 文档、审计记录、构建产物以及需要证明内容未被篡改的 OAuth2 令牌。PqcKeyPairGenerator生成 Kyber 和 Dilithium 密钥对,并作为自动配置的 Spring Bean 存在。
集成接口只有三行代码:
关于依赖的说明
Bouncy Castle(bcprov-jdk18on)向后兼容到 JDK 11,覆盖了多数处于 LTS 周期内的银行环境。如果你已经在使用 JDK 24 及以上版本,SunJCE Provider 现在原生支持 ML-KEM 和 ML-DSA,分别通过 JEP 496 和 JEP 497 提供,无需外部库:
Bouncy Castle 提供更多参数集灵活性,并且支持 JDK 11 和 JDK 17。而原生 Provider 零依赖,也是符合 NIST 标准的 Java 工具链正在汇聚的方向。如果你的银行本来就在规划 JDK 24 升级,原生路径值得采用。
用例 1:服务间负载加密
现状
交易服务通过 HTTP 向核心银行服务发送客户支付指令。TLS 保护了传输链路,但无法抵御 HNDL。攻击者今天记录下 RSA 密钥交换,将来可以用量子计算机解密整个会话。在典型的银行基础设施中,TLS 通常还会在 API 网关、服务网格和内部负载均衡器处终止,因此交易服务与核心银行服务之间的实际微服务跳转,在内部边界内往往根本未加密。
模式
在发送前,使用 Kyber+AES-256-GCM 对 HTTP 请求体进行加密,这与 TLS 无关。核心银行服务收到 PqcEncryptedPayload 记录后,用其 Kyber 私钥解密。即使完全去掉 TLS,支付指令也仍然受到保护。
这正是 NIST 在其迁移指南中描述的双层模式:TLS 应对经典攻击者,Kyber 应对量子攻击者。两者必须被独立攻破。你不需要改动 TLS 设置、API 网关配置或服务网格。
注意事项
Kyber-768 公钥约为 1,184 字节。这个大小放在 HTTP 请求体中没问题,但不要放在请求头中。Dilithium-3 签名约为 3,300 字节,如果你要将其序列化到 JWT 声明或 ISO 20022 消息信封中,这一点很重要。
用例 2:PII 和 KYC 字段级加密
现状
客户 SSN、税务识别号、出生日期字段和 KYC 文档引用通常存放在 PostgreSQL 中。它们可能在静态存储时经过 AES 加密,但密钥通常放在环境变量中,或在启动时从配置服务器拉取。一旦因 SQL 注入导致数据库被导出、备份配置错误或内部人员泄露,所有数据都会暴露。在零售银行中,仅是一份 SSN 泄露,就可能构成 GDPR、CCPA、GLBA 以及各州金融数据保护法律下的监管违规。
模式
在使用 Jakarta Persistence 持久化实体之前,用 PqcEncryptionService 对每个敏感字段进行加密。列中存储的是 Base64 编码的密文块。明文值使用 @Transient 注解标注,永远不会写入数据库。
阻碍字段级加密进入生产环境的密钥管理问题
上面的代码在开发环境中运行良好,但 masterKeyPair.getPrivate() 是放在 JVM 堆中的 Kyber 私钥。在银行语境下,这种做法会带来三个问题,并且无法通过任何安全审计:
- 服务器重启时如果没有持久化密钥库,所有加密的客户记录将永久不可读。
- 任意运行实例的堆转储都会暴露数据库中所有 SSN 和税号的主私钥。
- 没有密钥轮换,而 GLBA、PCI-DSS 和 SOC 2 都明确要求这一点。
解决办法是将所有 Kyber 密钥操作都通过 AWS KMS 或 HashiCorp Vault 进行。应用程序永远不持有原始私钥。每次解密都是一次有日志、可审计的 KMS 调用,并按计划进行密钥轮换。这种模式已被充分理解,但它本身是独立于加密功能的一项工程工作,必须在任何加密字段接近生产环境之前完成。否则,你所拥有的只是可用的概念验证,而不是可部署的系统。
用例 3:贷款协议和审计跟踪的文档签名
现状
零售银行每天都会签署贷款协议、开户合同和监管审计记录。这些文档归档期长达七到三十年。今天用 RSA 签署的贷款协议,到 2035 年左右签名将可以被伪造。银行如果在 2034 年才发现这一风险,将无法追溯性地重新签署过去十年的归档文档。这在法律风险和合规层面都是问题,例如欧盟的 DORA 和美国的 OCC 指引。
模式
在创建时就用 Dilithium 为每份长期文档签名。Dilithium 是一种基于格的算法,其安全假设不受 Shor 算法影响。今天创建的签名到 2045 年在密码学上仍然有效。
同样的模式也适用于 CI/CD 产物签名。部署到银行基础设施中的每个 JAR,都应该由构建流水线使用 Dilithium 签名。部署门禁会在执行任何 kubectl apply 命令之前验证签名。如果签名不匹配,部署中止并抛出 SecurityException。这可以发现产物仓库与生产环境之间的供应链注入;标准 TLS 无法检测到这一点,因为它发生在仓库边界内部。
在本文的四个模式中,文档和产物签名是最接近生产就绪的。它不依赖 KMS 先就位,签名密钥可以通过现有密钥基础设施管理,而且紧迫性论据足够具体,能够获得法律和合规团队的批准。
用例 4:核心银行服务的抗量子 OAuth2 令牌
在零售银行中,授权层比典型微服务场景更需要紧迫性。原因如下。短期客户会话令牌(RS256,15 分钟过期)确实是低优先级。令牌在任何人破解之前就已经没有价值。但银行场景中有两类令牌是另一回事:用于核心银行集成、欺诈检测引擎、SWIFT 网关连接器和 ACH 报告流水线的 OAuth2 服务账户令牌。这些令牌通常有效期长达数月或数年,存放在 CI/CD 保险库和基础设施自动化工具中。任何带有长期监管意义声明的令牌都一样。这些正是 HNDL 攻击所收集的目标。你的 SWIFT 连接器服务账户令牌,如果今天被窃取并存储,到 2031 年被解密,攻击者将来就能利用经过身份验证的访问权限,重放请求到你的核心银行 API。
模式
将服务账户令牌签名从 RS256 替换为 DILITHIUM3。JWT 结构完全相同,只有 alg 头和签名调用发生变化。
需要规划的事项
Dilithium-3 签名约为 3,300 字节,而 RS256 只有 256 字节。携带这种签名的 JWT 会明显变大。如果你的 API 网关有请求大小限制,或者你的 SWIFT 连接器对消息信封大小有严格要求,在推出此修复之前请检查这些约束。开源生态中针对 OAuth2 流程的完整 Spring Security 集成仍在推进中,因此请将该用例视为近期计划工作,而不是今天就可以上线的功能。
如何安排工作顺序
大多数团队不应试图一次性完成所有工作。在银行环境中,图 1 描述了风险排序:
[LOADING...]
图 1. 面向 Spring Boot 微服务、按风险优先级排序的 PQC 迁移顺序。(来源:作者制作)
立即进行以下修改:
- 为 Kyber 密钥管理接入 AWS KMS 或 HashiCorp Vault。没有这一步,其他任何工作都不具备生产安全性。
- 为承载最敏感数据的两到三个服务间流量添加 Kyber+AES-256-GCM 负载加密:任何涉及客户 PII、KYC 记录或支付指令的流量。
- 将贷款协议和监管文档签名切换到 Dilithium。这一项最有时效性,因为你无法事后修复已归档文档,而且它不需要先有 KMS。
在接下来六到十八个月内进行以下修改:
- 将负载加密推广到内部服务网格的其余部分。
- 使用 Jakarta Persistence/Hibernate ORM 字段加密辅助工具,从 KMS 进行按记录密钥派生。
- 为银行内部基础设施中的 CI/CD 产物添加 Dilithium 签名。
- 一旦 JEP 527 在即将发布的 JDK 27 中落地,并且你的云服务商支持新的密码套件,就在 TLS 1.3 中启用 PQC。
密钥管理稳定后,为服务账户增加 Dilithium OAuth2 令牌签名的 Spring Security 集成。接着,在 API 网关层为 Core Banking 和监管流水线端点添加支持 PQC 的令牌验证。
要避免的是把短期客户会话令牌作为起点,因为那是最熟悉的授权模式,但也是这个列表中风险最低的一项。从保质期最长、监管暴露最大的部分开始。
总结
零售银行 Spring Boot 服务群的 PQC 迁移不必一次性全部完成。NIST 标准已经定稿,JDK 24 提供了原生支持,Bouncy Castle 则覆盖了仍在使用 JDK 11 或 JDK 17 的团队。最紧迫的工作——内部服务流量的负载加密、长期文档的 Dilithium 签名、以及 PII 字段级加密——现在都可以通过一个库集成和一次专注的迭代来实现。难点不在于密码学本身,而在于底层密钥管理。没有 KMS 或 HashiCorp Vault,字段级加密就只是可运行的概念验证,无法通过银行安全审查。先把基础打牢,其余工作就能逐步推进。
关于作者
Pankaj Sharma
Pankaj Sharma 是首席软件工程师兼解决方案架构师,在金融服务领域拥有丰富的技术领导、系统设计和平台工程经验。他专注于大规模分布式系统、云原生应用安全(AppSec)和企业基础设施自动化,多年来一直为复杂、领域驱动的生态系统构建弹性后端架构和默认安全的流水线。他目前正在撰写关于后量子密码学(PQC)迁移模式以及面向处理客户 PII、支付处理和监管文档签名的 Spring Boot 平台的实用实施框架案例研究。Pankaj 通过技术写作和行业思想领导力,积极分享经过实战检验的工程经验与系统设计策略。
显示更多 显示更少