Article: Post-Quantum Cryptography in Spring Boot: Four Patterns You Can Ship This Sprint A new Spring Boot library, PqcStarterLib, offers four patterns for integrating post-quantum cryptography (PQC) into banking applications, including payload encryption, field-level encryption, document signing with Dilithium, and quantum-safe OAuth2 token signing. The article warns that adversaries are already storing encrypted traffic to decrypt later, and recommends prioritizing long-lived data such as loan agreements and KYC records, which will have forgeable RSA signatures by 2035. Key Takeaways - If you are already on JDK 24, you can start using the Module-Lattice-Based Key-Encapsulation Mechanism ML-KEM and Module-Lattice-Based Digital Signature Algorithm ML-DSA through the standard Java Cryptography Extension JCE API with no extra library. The JDK upgrade JDK 24 you were probably already planning also unblocks your entire post-quantum cryptography PQC migration. - Someone is storing your RSA-wrapped TLS sessions right now to decrypt later, so any customer SSNs, transaction records, and Know Your Customer KYC documents flowing between your services today are already at risk. Waiting for PQC TLS to arrive at your cloud provider is not a migration plan. - Encrypting a database field with a Kyber key is not the hard part; rather, the hard part is making sure that key does not live in your JVM heap, because one server restart or one heap dump undoes every encrypted row in your database. Kay Management Services KMS or HashiCorp Vault integration needs to come before anything is deployed to production. - OAuth2 tokens and service account credentials used by core banking, fraud detection, and regulatory reporting pipelines often live for months or years, making them a higher priority for PQC migration than short-lived customer session tokens. - Start your PQC migration with the data that lives the longest, not with the authorization layer that feels most familiar, because loan agreements and KYC records signed with RSA today will have forgeable signatures around 2035. Therefore, you cannot go back and re-sign archived documents after the fact. Background When NIST finalized the FIPS 203 https://csrc.nist.gov/pubs/fips/203/ipd and FIPS 204 https://csrc.nist.gov/pubs/fips/204/ipd specifications in August 2024, most engineering teams in regulated industries started asking the same question: "where do we actually begin?" The obvious answer is "switch to PQC TLS", but that is still rolling out across cloud providers and is something most teams cannot switch on today. Meanwhile, the actual risk, i.e., adversaries storing your encrypted inter-service traffic right now to decrypt it once quantum hardware catches up, is already in motion. Consider a standard retail banking microservice platform built on Spring Boot with a Transaction Service that posts payment instructions to a Core Banking Service as well as customer Personally Identifiable Information PII and KYC data in PostgreSQL. Additionally, the platform will have loan agreements, account opening documents archived in Amazon S3, and OAuth2 service account tokens wired into regulatory reporting pipelines for SWIFT and ACH connectors. This topology is completely typical for a mid-to-large bank. The question is what "quantum-safe" actually means for each of those pieces. The answer differs for every piece. This article works through four concrete patterns for that topology using a Spring Boot PQC library called PqcStarterLib https://github.com/catallicpankaj/pqc-starter-lib , which wraps a Bouncy Castle https://www.bouncycastle.org/ PQC provider behind three autoconfigured beans. The patterns cover payload encryption between internal banking services, PII and KYC field-level encryption before Jakarta Persistence writes to the database, long-lived document signing with Dilithium https://pq-crystals.org/dilithium/ for loan agreements and audit records, and quantum-safe OAuth2 token signing for service accounts used in Core Banking and regulatory pipelines. Each pattern comes with working Spring Boot code and an honest note on what blocks it from going straight to production. A retail bank is a particularly attractive Harvest Now, Decrypt Later HNDL target because the data has a very long shelf life. A customer SSN stolen today will still be useful in 2035. A loan agreement, whose RSA signature becomes forgeable in ten years, is a legal liability that cannot be fixed retroactively. The patterns in this article are designed around that reality. The Threat in Plain Terms RSA and ECDSA work because factoring large numbers and solving discrete logarithms are hard problems for classical computers. A quantum computer running Shor's Algorithm https://www.classiq.io/insights/shors-algorithm-explained solves both in polynomial time. IBM, Google, and several national labs have working quantum processors today, though none yet at the scale needed to break RSA-2048. Most experts put that crossover somewhere between 2030 and 2035. The part that cannot wait is HNDL. Adversaries are intercepting and storing encrypted TLS traffic right now. The RSA key exchange that establishes the TLS session is recorded alongside the ciphertext. Once a capable quantum computer exists, they go back and decrypt it. For a retail bank, what is in scope includes customer KYC data flowing between services, transaction records, inter-bank settlement messages, as well as any document transferred over the wire that needs to stay confidential for years. The other part that cannot wait is long-lived signed documents. If a loan agreement is signed today with RSA and will need to be held up legally in 2036, you have a problem that cannot be fixed after the fact. Banks archive loan agreements, account opening contracts, and audit trails exist for anywhere from seven to thirty years depending on regulatory jurisdiction. You cannot retroactively re-sign archived documents. Short-lived data are lower risk. A customer session token that expires in fifteen minutes is mostly fine even under an RSA signing key, because it is worthless before anyone can crack it. But OAuth2 service account tokens for Core Banking integrations, Fraud Detection pipelines, and SWIFT connectors that live for months are a different story. Those are exactly what HNDL attacks target. What PqcStarterLib Adds to Spring Boot PqcStarterLib is built on Bouncy Castle's implementation of FIPS 203 and FIPS 204. It exposes three Spring beans that autoconfigure on startup: provides hybrid encryption using Kyber KEM to establish a one-time shared secret, then AES-256-GCM to encrypt the actual payload. Use this service for any inter-service message body or database field that needs to stay confidential. PqcEncryptionService provides signing and verification using CRYSTALS-Dilithium. Use this service for loan agreements, KYC documents, audit records, build artifacts, and OAuth2 tokens where you need to prove content has not been altered. PqcSignatureService generates Kyber and Dilithium key pairs as autoconfigured Spring beans. PqcKeyPairGenerator The integration surface is three lines of code: @Autowired PqcEncryptionService pqc; @Autowired PqcSignatureService pqcSig; byte ciphertext = pqc.encrypt data, recipientPublicKey .toBytes ; byte signature = pqcSig.sign document, myPrivateKey ; boolean ok = pqcSig.verify document, signature, myPublicKey ; A Note on Dependencies Bouncy Castle bcprov-jdk18on https://central.sonatype.com/artifact/org.bouncycastle/bcprov-jdk18on is backwards compatible to JDK 11, which covers most banking shops on LTS cycles. If you are on JDK 24+, the provider now includes ML-KEM and ML-DSA natively via https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java SunJCE JEP 496 https://openjdk.org/jeps/496 and JEP 497 https://openjdk.org/jeps/497 , respectively. There is no external library required: // JDK 24+ only, no Bouncy Castle required KeyPairGenerator kpg = KeyPairGenerator.getInstance "ML-KEM-768" ; KeyPair kyberPair = kpg.generateKeyPair ; Signature signer = Signature.getInstance "ML-DSA-65" ; signer.initSign dilithiumPrivateKey ; signer.update message ; byte sig = signer.sign ; Bouncy Castle gives you more parameter set flexibility and works on JDK 11 and JDK 17. The native provider has zero dependencies and is what NIST-standard Java tooling is converging on. If your bank is planning a JDK 24 upgrade anyway, the native path is worth taking. Use Case 1: Inter-Service Payload Encryption The Situation Transaction Service posts customer payment instructions to Core Banking Service over HTTP. TLS protects the wire, but not against HNDL. An adversary who records the RSA key exchange today can decrypt the full session later with a quantum computer. In typical banking infrastructure, TLS also gets terminated at API gateways, service meshes, and internal load balancers, so the actual microservice hop between Transaction Service and Core Banking is often unencrypted inside the perimeter anyway. The Pattern Encrypt the HTTP body with Kyber+AES-256-GCM before sending, independent of TLS. Core Banking Service receives a PqcEncryptedPayload https://github.com/catallicpankaj/pqc-starter-lib/blob/main/src/main/java/com/pqc/hybrid/crypto/PqcEncryptedPayload.java record and decrypts it with its Kyber private key. The payment instruction is protected even if TLS is stripped entirely. // Transaction Service: sender @Autowired PqcEncryptionService pqc; PaymentInstruction instruction = buildInstruction transfer ; byte payload = objectMapper.writeValueAsBytes instruction ; PqcEncryptedPayload encrypted = pqc.encrypt payload, coreBankingPublicKey // Kyber-768 public key ; restTemplate.postForObject "/core-banking/process", encrypted, Void.class ; // Core Banking Service: receiver @PostMapping "/core-banking/process" public ResponseEntity