← All recipes
Moderne licensed

Offer a hybrid ML-KEM key exchange group first

Recipe IDio.moderne.cryptography.pqc.AddHybridTlsNamedGroupArtifactio.moderne.recipe:rewrite-cryptography

Prepends an ML-KEM hybrid key-exchange group to explicitly configured named-group lists, so that a connection whose groups are pinned can still negotiate post-quantum key exchange. Covers SSLParameters.setNamedGroups and BCSSLParameters.setNamedGroups with a literal array or a same-class private array constant, and System.setProperty("jdk.tls.namedGroups", ...) with a literal value. The group goes first because first means most preferred, which is where JDK 27 puts it by default and where BouncyCastle 1.81 does not — BCJSSE enables the hybrid last, so an explicit hybrid-first list still changes the key share that is offered. Sites that already name any ML-KEM group are left alone silently and produce no row: setNamedGroups throws on a duplicate element, so re-running this recipe has to be a no-op rather than a reordering. Code that configures no named groups at all is deliberately not touched — on JDK 27 that absence is the good state, and inserting a literal list would freeze today's defaults forever. -D flags in shell scripts, Dockerfiles and orchestration manifests are outside a source scan and need a manual audit.

Single recipeProprietary

Usage

This recipe has no required configuration options. You’ll need the Moderne CLI configured before running the command below.

mod run . --recipe io.moderne.cryptography.pqc.AddHybridTlsNamedGroup

If the recipe isn’t available locally, install it with:

mod config recipes jar install io.moderne.recipe:rewrite-cryptography:RELEASE

Options

NameTypeDescription
hybridGroupStringThe hybrid named group to offer first. Kept as a single option on purpose: draft-ietf-tls-ecdhe-mlkem is still an IETF draft, so a rename at RFC promotion is a one-line default change rather than a sweep through the recipes. Default X25519MLKEM768, which is what JEP 527 puts first in the JDK 27 provider default.
e.g. SecP256r1MLKEM768
modeStringrewrite (the default) prepends the hybrid group. report leaves every site untouched and only marks it and records a row — for estates whose group pins are deliberate, typically because a middlebox chokes on the larger ML-KEM key share or because ClientHello size is constrained.
e.g. report
skipTestSourcesBooleanLeave test sources alone. A protocol test very often enables a legacy version on purpose so it can assert that the version is refused, so rewriting it hardens nothing and deletes the coverage that proves the hardening works. Set to false to rewrite tests as well, which is only useful once the production code is already enforced. Default true.

Data tables

Structured output this recipe can produce.

  • Hybrid TLS key exchange enforcementNamed-group configuration rewritten to offer an ML-KEM hybrid group first, and sites flagged as needing manual review because the value is not statically resolvable or the transformation would need a BouncyCastle upgrade to compile. `-D` flags outside the scanned repository are invisible, so an unchanged repository is not evidence of a hybrid-ready runtime.io.moderne.cryptography.pqc.table.HybridKexEnforcementTable
  • Source files that had resultsSource files that were modified by the recipe run.org.openrewrite.table.SourcesFileResults
  • Source files that had search resultsSearch results that were found during the recipe run.org.openrewrite.table.SearchResults
  • Source files that errored on a recipeThe details of all errors produced by a recipe run.org.openrewrite.table.SourcesFileErrors
  • Recipe performanceStatistics used in analyzing the performance of recipes.org.openrewrite.table.RecipeRunStats