From fbb6c26d8d7776facf2fee9f0e529f8f923b6200 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 30 Jul 2026 03:21:32 +0000 Subject: [PATCH 1/6] docs: add Post-Quantum Cryptography (PQC) User Guide --- docs/post_quantum_cryptography_guide.md | 281 ++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 docs/post_quantum_cryptography_guide.md diff --git a/docs/post_quantum_cryptography_guide.md b/docs/post_quantum_cryptography_guide.md new file mode 100644 index 000000000000..418e62a87486 --- /dev/null +++ b/docs/post_quantum_cryptography_guide.md @@ -0,0 +1,281 @@ +# Post-Quantum Cryptography (PQC) User Guide for Java Client Libraries + +## Overview + +**Post-Quantum Cryptography (PQC)** refers to cryptographic algorithms designed to secure communications against future attacks by quantum computers. Quantum computers utilizing Shor's algorithm threaten traditional public-key algorithms (such as RSA and ECDH key exchange) by making it possible to retroactively decrypt intercepted TLS communications ("store-now, decrypt-later" attacks). + +Google Cloud Java client libraries (via `gax-grpc` and `gax-httpjson`) provide out-of-the-box support for **hybrid PQC key exchange** (combining classical algorithms like `X25519` with post-quantum key encapsulation mechanisms like `ML-KEM-768` / `X25519MLKEM768`). This hybrid approach guarantees that security is at least as strong as traditional TLS 1.3 even if post-quantum algorithms encounter unforeseen implementation flaws, while protecting present-day encrypted traffic against future quantum decryption. + +--- + +## Default Behavior + +PQC support is **enabled by default** for both **gRPC** (`gax-grpc`) and **HTTP/JSON** (REST, `gax-httpjson`) transports in Google Cloud Java client libraries whenever native BoringSSL/Conscrypt libraries are available on the runtime environment. + +### Transport Support Summary + +| Transport | GAX Module | Underlying Transport Library | Native Engine | PQC Activation | +| :--- | :--- | :--- | :--- | :--- | +| **HTTP/JSON** | `gax-httpjson` | Google HTTP Client (`NetHttpTransport`) | Conscrypt (BoringSSL JNI) | Enabled via `google-http-java-client` Conscrypt provider API | +| **gRPC** | `gax-grpc` | gRPC-Java (`grpc-netty-shaded` / Netty) | Netty-tcnative (BoringSSL JNI) or Conscrypt | Built-in via gRPC-Java v1.83.0+ | + +--- + +## Transport Implementation Details + +The underlying TLS implementation and configuration mechanism differs between HTTP/JSON and gRPC. + +### 1. HTTP/JSON Transport (`gax-httpjson` & `google-http-java-client`) + +For REST/HTTP transport, PQC enablement relies on updates introduced in `google-http-java-client`: + +- **`google-http-java-client` API Enhancements**: `NetHttpTransport.Builder` introduced `.setSecurityProvider(Provider)` and `.setSslSocketConfigurator(...)`. This allows higher-level libraries (like GAX) to register a specific Security Provider and customize `SSLSocket` / `SSLEngine` instances created by standard Java `HttpsURLConnection`. +- **GAX Integration (`HttpJsonConscryptUtils`)**: GAX uses these APIs to register **Conscrypt** as the security provider and set a socket configurator (`Conscrypt.setUseEngineSocket(socket, true)`). +- **TLS 1.3 Negotiation**: When HTTPS connections are opened, Conscrypt advertises `X25519MLKEM768` to Google Front End (GFE) endpoints during the TLS 1.3 handshake. + +``` ++-------------------------------------------------------------------+ +| GAPIC HTTP/JSON Client Request | ++-------------------------------------------------------------------+ + | + Is Conscrypt JNI Available on Platform? + | + +----------------+----------------+ + | | + [ YES ] [ NO ] + | | + v v + google-http-client registers Conscrypt Falls back to JDK TLS (JSSE) + Offers X25519MLKEM768 (PQC) Offers Classical TLS (X25519) +``` + +### 2. gRPC Transport (`gax-grpc` & gRPC-Java v1.83.0+) + +For gRPC transport, PQC key exchange is built into **gRPC-Java v1.83.0+**: + +- **BoringSSL under the Hood**: gRPC-Java (`grpc-netty-shaded`) defaults to Netty's `netty-tcnative` (Netty's Tomcat Native JNI wrapper around **BoringSSL**). Like Conscrypt, it uses BoringSSL for C-level cryptographic execution. +- **gRPC-Java v1.83.0+ PQC Support**: Starting in version 1.83.0, `grpc-netty-shaded` has PQC hybrid key exchange (`X25519MLKEM768`) enabled by default for TLS 1.3 connections. +- **ALPN & Channel Pooling**: gRPC-Java advertises HTTP/2 (`h2`) via ALPN while offering `X25519MLKEM768` in the ClientHello. This negotiation operates seamlessly across all channels in GAX's `ChannelPoolSettings`. + +``` ++-------------------------------------------------------------------+ +| GAPIC gRPC Client Request | ++-------------------------------------------------------------------+ + | + gRPC-Java v1.83.0+ Netty Channel Builder + | + Is Netty-tcnative / Conscrypt JNI Available? + | + +----------------+----------------+ + | | + [ YES ] [ NO ] + | | + v v + Netty SSLContext uses BoringSSL/Conscrypt Netty uses Standard JDK JSSE + Offers X25519MLKEM768 (PQC) Offers Classical TLS (X25519) +``` + +--- + +## Conscrypt Capabilities & Supported Algorithms + +Conscrypt provides high-performance TLS and cryptographic operations by wrapping BoringSSL via JNI native libraries. + +> [!NOTE] +> For a full, up-to-date listing of named groups and capabilities supported across Conscrypt versions, refer to the official [Conscrypt Capabilities Documentation](https://github.com/google/conscrypt/blob/2.6.0/CAPABILITIES.md#supported-named-groups). + +### Supported PQC & Hybrid Key Exchange Groups + +Conscrypt supports several post-quantum and hybrid named groups for TLS 1.3 key exchange: + +| Named Group Identifier | Description | Status in Conscrypt | +| :--- | :--- | :--- | +| `X25519MLKEM768` | Primary hybrid group combining X25519 ECDH with NIST FIPS 203 ML-KEM-768. | Recommended / Offered by Default | +| `SecP256r1MLKEM768` | Hybrid group combining NIST P-256 (secp256r1) with ML-KEM-768. | Supported | +| `X25519Kyber768Draft00` | Pre-standardization draft hybrid group combining X25519 with Kyber-768. | Legacy / Supported for backward compatibility | +| `MLKEM1024` | Standalone high-security post-quantum key encapsulation mechanism. | Supported | + +### Supported Classical (Non-PQC) Groups + +For environments or server endpoints where PQC key exchange is disabled or unsupported, Conscrypt falls back to classical named groups: + +- `X25519` (Curve25519 ECDH) +- `SecP256r1` (NIST P-256 ECDH) +- `SecP384r1` (NIST P-384 ECDH) +- `SecP521r1` (NIST P-521 ECDH) + +### What to Do If a Required Algorithm Is Unsupported + +If your application or security policy mandates a specific PQC algorithm variant that Conscrypt does not support (or if you must use a custom security module): +1. Configure a custom Security Provider (such as Bouncy Castle) as described in [Alternatives & How to Configure Them](#alternatives--how-to-configure-them). +2. Explicitly override the transport builder's channel provider or `SSLContext`. + +--- + +## Limitations of Native PQC Engines (Conscrypt & Netty-tcnative) + +Both HTTP/JSON (via Conscrypt) and gRPC (via Netty-tcnative / BoringSSL) rely on C native shared libraries loaded via JNI. Consequently, **both transports share the same platform limitations**: + +1. **JNI Native Binary Dependencies**: + - Conscrypt uses `conscrypt-openjdk-uber`, which extracts `.so`, `.dylib`, or `.dll` native libraries into temporary directories at runtime. + - `grpc-netty-shaded` embeds pre-compiled `netty-tcnative` BoringSSL native libraries into its JAR. + +2. **System & GLIBC Compatibility Constraints**: + - **Linux glibc Versioning**: Native C binaries require compatible C runtime (`glibc`) versions (e.g. `GLIBC_2.35+`). Older Linux enterprise distributions or base images with older `glibc` releases will fail to load native libraries (`UnsatisfiedLinkError`). + - **Restricted / Read-Only Filesystems**: Environments that mount `/tmp` with `noexec`, strict container runtimes, Android/GraalVM native images without JNI support, or security managers blocking C library loading will prevent native PQC initialization. + +3. **Graceful Fallback Behavior**: + When native C libraries fail to load for either transport, the client libraries safely fall back to standard JDK JSSE: + ``` + WARNING: Conscrypt native libraries not available. Falling back to JDK TLS. + java.lang.UnsatisfiedLinkError: ... libc.so.6: version `GLIBC_2.35' not found + ``` + The client will continue operating using classical TLS provided by the JDK. + +--- + +## Alternatives & How to Configure Them + +If you need to disable PQC, force classical key exchange, or use a custom TLS engine, you can configure alternative transport providers for both gRPC and HTTP/JSON. + +### Alternative 1: Forcing Classical (Non-PQC) Key Exchange (HTTP/JSON) + +To explicitly force classical key exchange (such as `X25519` or `SecP256r1`) for HTTP/JSON clients: + +```java +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.gax.httpjson.HttpJsonConscryptUtils; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; +import org.conscrypt.Conscrypt; + +// Step 1: Create NetHttpTransport configured with explicit classical named groups +NetHttpTransport transport = + HttpJsonConscryptUtils.configureConscryptSecurityProvider(new NetHttpTransport.Builder()) + .setSslSocketConfigurator( + socket -> { + if (Conscrypt.isConscrypt(socket)) { + try { + // Explicitly offer only classical X25519 (disabling PQC hybrid groups) + Conscrypt.setNamedGroups(socket, new String[] {"X25519"}); + } catch (Exception e) { + // Handle or log socket configuration failure + } + } + }) + .build(); + +// Step 2: Build transport channel provider using custom transport +InstantiatingHttpJsonChannelProvider transportChannelProvider = + SecretManagerServiceSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport(transport) + .build(); + +// Step 3: Instantiate client with settings +SecretManagerServiceSettings settings = + SecretManagerServiceSettings.newHttpJsonBuilder() + .setTransportChannelProvider(transportChannelProvider) + .build(); +``` + +### Alternative 2: Forcing Classical (Non-PQC) Key Exchange (gRPC) + +For gRPC clients, you can configure `InstantiatingGrpcChannelProvider` with custom Netty SSL context options to restrict key exchange groups: + +```java +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; + +InstantiatingGrpcChannelProvider transportChannelProvider = + SecretManagerServiceSettings.defaultGrpcTransportProviderBuilder() + .setChannelConfigurator( + managedChannelBuilder -> { + // Custom channel configuration to override SSL/TLS settings + }) + .build(); + +SecretManagerServiceSettings settings = + SecretManagerServiceSettings.newBuilder() + .setTransportChannelProvider(transportChannelProvider) + .build(); +``` + +### Alternative 3: Bypassing Conscrypt to Use Standard JDK JSSE (HTTP/JSON) + +If you prefer to bypass Conscrypt completely and use the standard JDK JSSE provider: + +```java +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; + +// Build standard NetHttpTransport without Conscrypt configuration +NetHttpTransport standardTransport = new NetHttpTransport.Builder().build(); + +InstantiatingHttpJsonChannelProvider transportProvider = + SecretManagerServiceSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport(standardTransport) + .build(); + +SecretManagerServiceSettings settings = + SecretManagerServiceSettings.newHttpJsonBuilder() + .setTransportChannelProvider(transportProvider) + .build(); + +try (SecretManagerServiceClient client = SecretManagerServiceClient.create(settings)) { + // Client uses standard JDK JSSE TLS +} +``` + +### Alternative 4: Configuring Custom Security Providers (e.g., Bouncy Castle) + +To use a third-party Security Provider (such as Bouncy Castle) for TLS: + +```java +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import java.security.Provider; +import java.security.Security; +import javax.net.ssl.SSLContext; + +// Register custom provider +Provider customProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider(); +Security.addProvider(customProvider); + +// Initialize custom SSLContext +SSLContext sslContext = SSLContext.getInstance("TLS", customProvider); +sslContext.init(null, null, null); + +// Configure transport builder with custom SSLSocketFactory +NetHttpTransport customTransport = + new NetHttpTransport.Builder() + .setSslSocketFactory(sslContext.getSocketFactory()) + .build(); + +InstantiatingHttpJsonChannelProvider transportProvider = + SecretManagerServiceSettings.defaultHttpJsonTransportProviderBuilder() + .setHttpTransport(customTransport) + .build(); +``` + +--- + +## Future Roadmap: JDK 27+ and Native JDK PQC Support + +As quantum-resistant cryptography standards mature, Java is incorporating native PQC support directly into standard OpenJDK distributions. + +> [!IMPORTANT] +> **JDK 27+ Native PQC Support**: +> Starting with JDK 27, standard JDK Security Providers (SunJSSE) will include native support for NIST post-quantum key encapsulation standards (JEP / ML-KEM). + +### What JDK 27+ Means for Java SDK Users + +1. **Zero-Dependency Native PQC**: + On JDK 27 and future Java LTS releases, applications running standard OpenJDK will automatically negotiate PQC key exchange natively out-of-the-box—even without Conscrypt or JNI native dependencies. + +2. **Forward Compatibility**: + The GAX transport layer (`gax-grpc` and `gax-httpjson`) is designed so that when running on JDK 27+: + - If native BoringSSL libraries (Conscrypt / Netty-tcnative) are present, they continue to offer hardware-accelerated PQC key exchange. + - If native libraries are absent or disabled, the JDK's standard JSSE provider natively offers ML-KEM PQC key exchange. + - Applications do not need to make any code or configuration changes when upgrading to JDK 27+. From 8248bc36d29793bc0f5d9846f2e87c1378fc890c Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 30 Jul 2026 16:53:38 +0000 Subject: [PATCH 2/6] docs: refine PQC user guide for HTTP/JSON transport with verification steps and locally scoped security providers --- docs/post_quantum_cryptography_guide.md | 258 ++++++++++++------------ 1 file changed, 131 insertions(+), 127 deletions(-) diff --git a/docs/post_quantum_cryptography_guide.md b/docs/post_quantum_cryptography_guide.md index 418e62a87486..3c6404806d0c 100644 --- a/docs/post_quantum_cryptography_guide.md +++ b/docs/post_quantum_cryptography_guide.md @@ -1,151 +1,167 @@ -# Post-Quantum Cryptography (PQC) User Guide for Java Client Libraries +# Post-Quantum Cryptography (PQC) User Guide for HTTP/JSON Java Client Libraries -## Overview +## 1. The Quantum Threat & Why PQC is Critical -**Post-Quantum Cryptography (PQC)** refers to cryptographic algorithms designed to secure communications against future attacks by quantum computers. Quantum computers utilizing Shor's algorithm threaten traditional public-key algorithms (such as RSA and ECDH key exchange) by making it possible to retroactively decrypt intercepted TLS communications ("store-now, decrypt-later" attacks). +### The Problem: Store-Now, Decrypt-Later (SNDL) Attacks +Traditional Transport Layer Security (TLS) relies on classical asymmetric public-key cryptography—such as RSA, Elliptic Curve Diffie-Hellman (`ECDH`), and `X25519`—to establish secure encrypted connections. While these classical algorithms are computationally secure against present-day classical computers, they are vulnerable to **Shor's algorithm** running on a cryptographically relevant quantum computer (CRQC). -Google Cloud Java client libraries (via `gax-grpc` and `gax-httpjson`) provide out-of-the-box support for **hybrid PQC key exchange** (combining classical algorithms like `X25519` with post-quantum key encapsulation mechanisms like `ML-KEM-768` / `X25519MLKEM768`). This hybrid approach guarantees that security is at least as strong as traditional TLS 1.3 even if post-quantum algorithms encounter unforeseen implementation flaws, while protecting present-day encrypted traffic against future quantum decryption. +An adversary does not need to wait for a quantum computer to be built before attacking classical encryption: +- **Harvest Now, Decrypt Later**: Threat actors can intercept and store encrypted TLS network traffic today. +- **Future Decryption**: Once a sufficiently powerful quantum computer becomes operational, adversaries will be able to retroactively break the classical Diffie-Hellman key exchange and decrypt long-lived confidential data collected years earlier. + +### The Consequence of Not Using PQC +Without Post-Quantum Cryptography (PQC), any sensitive data transmitted across networks today—including authentication credentials, financial records, proprietary algorithms, and customer data—remains vulnerable to retroactive decryption in the future. + +### The Solution: Hybrid PQC Key Exchange +To mitigate this threat immediately without sacrificing present-day security, Google Cloud HTTP/JSON Java client libraries support **Hybrid PQC Key Exchange**. +- A hybrid key exchange combines a classical ECDH algorithm (such as `X25519`) with a NIST-standardized Post-Quantum Key Encapsulation Mechanism (KEM), such as **ML-KEM-768** (FIPS 203), negotiated as `X25519MLKEM768`. +- This ensures that your communications remain at least as secure as standard classical TLS 1.3 against present-day attacks, while simultaneously protecting encrypted sessions against future quantum decryption. --- -## Default Behavior +## 2. Overview & Default Behavior in `gax-httpjson` -PQC support is **enabled by default** for both **gRPC** (`gax-grpc`) and **HTTP/JSON** (REST, `gax-httpjson`) transports in Google Cloud Java client libraries whenever native BoringSSL/Conscrypt libraries are available on the runtime environment. +PQC support is **enabled by default** for **HTTP/JSON** (REST) transport in Google Cloud Java client libraries (`gax-httpjson`) whenever native Conscrypt / BoringSSL libraries are supported on the runtime environment. + +> [!NOTE] +> This guide currently focuses on **HTTP/JSON (`gax-httpjson`)** client libraries. Support for gRPC (`gax-grpc`) is under active development and will be detailed in an upcoming release. ### Transport Support Summary -| Transport | GAX Module | Underlying Transport Library | Native Engine | PQC Activation | +| Transport | GAX Module | Underlying HTTP Client | Cryptographic Engine | PQC Activation | | :--- | :--- | :--- | :--- | :--- | -| **HTTP/JSON** | `gax-httpjson` | Google HTTP Client (`NetHttpTransport`) | Conscrypt (BoringSSL JNI) | Enabled via `google-http-java-client` Conscrypt provider API | -| **gRPC** | `gax-grpc` | gRPC-Java (`grpc-netty-shaded` / Netty) | Netty-tcnative (BoringSSL JNI) or Conscrypt | Built-in via gRPC-Java v1.83.0+ | +| **HTTP/JSON** | `gax-httpjson` | Google HTTP Client (`NetHttpTransport`) | Conscrypt (BoringSSL JNI) | **Enabled by Default** via `google-http-java-client` security provider API | --- -## Transport Implementation Details +## 3. How to Verify That You Are Using PQC -The underlying TLS implementation and configuration mechanism differs between HTTP/JSON and gRPC. +You can verify that your HTTP/JSON client library is actively negotiating Post-Quantum Cryptography through operational logs, debug logging, or network traffic analysis. -### 1. HTTP/JSON Transport (`gax-httpjson` & `google-http-java-client`) - -For REST/HTTP transport, PQC enablement relies on updates introduced in `google-http-java-client`: - -- **`google-http-java-client` API Enhancements**: `NetHttpTransport.Builder` introduced `.setSecurityProvider(Provider)` and `.setSslSocketConfigurator(...)`. This allows higher-level libraries (like GAX) to register a specific Security Provider and customize `SSLSocket` / `SSLEngine` instances created by standard Java `HttpsURLConnection`. -- **GAX Integration (`HttpJsonConscryptUtils`)**: GAX uses these APIs to register **Conscrypt** as the security provider and set a socket configurator (`Conscrypt.setUseEngineSocket(socket, true)`). -- **TLS 1.3 Negotiation**: When HTTPS connections are opened, Conscrypt advertises `X25519MLKEM768` to Google Front End (GFE) endpoints during the TLS 1.3 handshake. +### 1. Check Operational Log Messages +When Conscrypt initializes successfully and configures PQC named groups, **no warning logs are emitted**. +If your environment cannot load native Conscrypt libraries or cannot configure PQC groups, the library emits a concise, one-line warning at `Level.WARNING` and safely falls back to standard JDK TLS: ``` -+-------------------------------------------------------------------+ -| GAPIC HTTP/JSON Client Request | -+-------------------------------------------------------------------+ - | - Is Conscrypt JNI Available on Platform? - | - +----------------+----------------+ - | | - [ YES ] [ NO ] - | | - v v - google-http-client registers Conscrypt Falls back to JDK TLS (JSSE) - Offers X25519MLKEM768 (PQC) Offers Classical TLS (X25519) +WARNING: Conscrypt native libraries not available. Falling back to JDK TLS. ``` +If you **do not see this warning message** in your application logs, Conscrypt has successfully initialized and enabled PQC key exchange. + +### 2. Enable Debug Logging (`Level.FINE`) +To inspect the exact initialization status and any underlying native library loader exceptions, enable debug logging (`Level.FINE`) for `com.google.api.gax.httpjson.HttpJsonConscryptUtils`: + +- In `logging.properties`: + ```properties + com.google.api.gax.httpjson.HttpJsonConscryptUtils.level = FINE + ``` +- If an error occurs during initialization, the full exception stacktrace (`UnsatisfiedLinkError`, `LinkageError`, etc.) will appear only at `FINE` level: + ``` + FINE: Conscrypt initialization failed with exception: java.lang.UnsatisfiedLinkError: ... + ``` -### 2. gRPC Transport (`gax-grpc` & gRPC-Java v1.83.0+) +### 3. Packet & Handshake Inspection +During a TLS 1.3 handshake with Google Front End (GFE) services, you can verify PQC negotiation using network analysis tools (such as Wireshark or OpenSSL `s_client`): +- **ClientHello**: Inspect the TLS `supported_groups` extension (Extension 10). When PQC is active, `X25519MLKEM768` (Group ID `0x4543` / `17731` or standardized IANA PQC identifier) is advertised in the ClientHello. +- **ServerHello**: The GFE endpoint selects `X25519MLKEM768` in the `key_share` extension, confirming that hybrid post-quantum key agreement was established for the connection. -For gRPC transport, PQC key exchange is built into **gRPC-Java v1.83.0+**: +--- + +## 4. HTTP/JSON Transport Implementation Details (`gax-httpjson` & `google-http-java-client`) -- **BoringSSL under the Hood**: gRPC-Java (`grpc-netty-shaded`) defaults to Netty's `netty-tcnative` (Netty's Tomcat Native JNI wrapper around **BoringSSL**). Like Conscrypt, it uses BoringSSL for C-level cryptographic execution. -- **gRPC-Java v1.83.0+ PQC Support**: Starting in version 1.83.0, `grpc-netty-shaded` has PQC hybrid key exchange (`X25519MLKEM768`) enabled by default for TLS 1.3 connections. -- **ALPN & Channel Pooling**: gRPC-Java advertises HTTP/2 (`h2`) via ALPN while offering `X25519MLKEM768` in the ClientHello. This negotiation operates seamlessly across all channels in GAX's `ChannelPoolSettings`. +PQC enablement for REST/HTTP transport relies on architecture enhancements in `google-http-java-client` and `gax-httpjson`: + +1. **`NetHttpTransport.Builder` API Enhancements**: + - `NetHttpTransport.Builder` provides `.setSecurityProvider(Provider)` and `.setSslSocketConfigurator(SslSocketConfigurator)`. + - This allows GAX to inject an explicit cryptographic `Provider` and configure raw `SSLSocket` instances created by standard Java `HttpsURLConnection`. +2. **GAX Conscrypt Registration (`HttpJsonConscryptUtils`)**: + - `InstantiatingHttpJsonChannelProvider` automatically invokes `HttpJsonConscryptUtils.configureConscryptSecurityProvider(builder)`. + - This registers Conscrypt as the socket provider and attaches a socket configurator that enables BoringSSL engine sockets (`Conscrypt.setUseEngineSocket(socket, true)`) and prefers hybrid PQC groups (`Conscrypt.setNamedGroups(socket, new String[] {"X25519MLKEM768", ...})`). +3. **TLS 1.3 Handshake Negotiation**: + - When HTTP connections are established, Conscrypt advertises `X25519MLKEM768` to Google Cloud endpoints, establishing a quantum-resistant TLS 1.3 channel. ``` +-------------------------------------------------------------------+ -| GAPIC gRPC Client Request | +| GAPIC HTTP/JSON Client Request | +-------------------------------------------------------------------+ | - gRPC-Java v1.83.0+ Netty Channel Builder - | - Is Netty-tcnative / Conscrypt JNI Available? + Is Conscrypt JNI Available on Platform? | +----------------+----------------+ | | [ YES ] [ NO ] | | v v - Netty SSLContext uses BoringSSL/Conscrypt Netty uses Standard JDK JSSE - Offers X25519MLKEM768 (PQC) Offers Classical TLS (X25519) + google-http-client uses Conscrypt Falls back to JDK JSSE + Offers X25519MLKEM768 (PQC Hybrid) Offers Classical X25519 ``` --- -## Conscrypt Capabilities & Supported Algorithms +## 5. Conscrypt Capabilities & Supported Algorithms Conscrypt provides high-performance TLS and cryptographic operations by wrapping BoringSSL via JNI native libraries. > [!NOTE] -> For a full, up-to-date listing of named groups and capabilities supported across Conscrypt versions, refer to the official [Conscrypt Capabilities Documentation](https://github.com/google/conscrypt/blob/2.6.0/CAPABILITIES.md#supported-named-groups). +> For a full listing of named groups and capabilities supported across Conscrypt versions, refer to the official [Conscrypt Capabilities Documentation](https://github.com/google/conscrypt/blob/2.6.0/CAPABILITIES.md#supported-named-groups). ### Supported PQC & Hybrid Key Exchange Groups -Conscrypt supports several post-quantum and hybrid named groups for TLS 1.3 key exchange: - | Named Group Identifier | Description | Status in Conscrypt | | :--- | :--- | :--- | -| `X25519MLKEM768` | Primary hybrid group combining X25519 ECDH with NIST FIPS 203 ML-KEM-768. | Recommended / Offered by Default | -| `SecP256r1MLKEM768` | Hybrid group combining NIST P-256 (secp256r1) with ML-KEM-768. | Supported | -| `X25519Kyber768Draft00` | Pre-standardization draft hybrid group combining X25519 with Kyber-768. | Legacy / Supported for backward compatibility | -| `MLKEM1024` | Standalone high-security post-quantum key encapsulation mechanism. | Supported | +| **`X25519MLKEM768`** | Primary hybrid group combining X25519 ECDH with NIST FIPS 203 ML-KEM-768. | Recommended / Offered by Default | +| **`SecP256r1MLKEM768`** | Hybrid group combining NIST P-256 (`secp256r1`) with ML-KEM-768. | Supported | +| **`X25519Kyber768Draft00`** | Pre-standardization draft hybrid group combining X25519 with Kyber-768. | Legacy / Backward compatible | +| **`MLKEM1024`** | Standalone high-security post-quantum key encapsulation mechanism. | Supported | ### Supported Classical (Non-PQC) Groups -For environments or server endpoints where PQC key exchange is disabled or unsupported, Conscrypt falls back to classical named groups: - +For environments or endpoints where PQC key exchange is disabled or unsupported, Conscrypt falls back to standard classical named groups: - `X25519` (Curve25519 ECDH) - `SecP256r1` (NIST P-256 ECDH) - `SecP384r1` (NIST P-384 ECDH) - `SecP521r1` (NIST P-521 ECDH) -### What to Do If a Required Algorithm Is Unsupported +--- -If your application or security policy mandates a specific PQC algorithm variant that Conscrypt does not support (or if you must use a custom security module): -1. Configure a custom Security Provider (such as Bouncy Castle) as described in [Alternatives & How to Configure Them](#alternatives--how-to-configure-them). -2. Explicitly override the transport builder's channel provider or `SSLContext`. +## 6. Platform Compatibility & Native Library Limitations ---- +Because Conscrypt relies on C native shared libraries (`conscrypt-openjdk-uber`) loaded via Java Native Interface (JNI), PQC support depends on OS platform compatibility: + +1. **System & GLIBC Compatibility Constraints**: + - **Linux glibc Versioning**: Conscrypt native C binaries require compatible C runtime (`glibc`) versions (such as `GLIBC_2.35+`). Older Linux distributions or lightweight images (such as Alpine Linux using `musl` libc) will fail to load native libraries (`UnsatisfiedLinkError`). + - **Restricted Filesystems**: Operating systems that mount `/tmp` with `noexec`, strict container security profiles, or environments blocking JNI library extraction will prevent Conscrypt from initializing. -## Limitations of Native PQC Engines (Conscrypt & Netty-tcnative) +2. **Graceful Fallback Behavior**: + - Whenever native library loading fails, `gax-httpjson` catches the error, logs a concise warning at `Level.WARNING`, and safely falls back to standard JDK JSSE: + ``` + WARNING: Conscrypt native libraries not available. Falling back to JDK TLS. + ``` + - Your application will continue running normally using classical TLS provided by the JDK. -Both HTTP/JSON (via Conscrypt) and gRPC (via Netty-tcnative / BoringSSL) rely on C native shared libraries loaded via JNI. Consequently, **both transports share the same platform limitations**: +--- -1. **JNI Native Binary Dependencies**: - - Conscrypt uses `conscrypt-openjdk-uber`, which extracts `.so`, `.dylib`, or `.dll` native libraries into temporary directories at runtime. - - `grpc-netty-shaded` embeds pre-compiled `netty-tcnative` BoringSSL native libraries into its JAR. +## 7. Mutual TLS (mTLS) Support with PQC -2. **System & GLIBC Compatibility Constraints**: - - **Linux glibc Versioning**: Native C binaries require compatible C runtime (`glibc`) versions (e.g. `GLIBC_2.35+`). Older Linux enterprise distributions or base images with older `glibc` releases will fail to load native libraries (`UnsatisfiedLinkError`). - - **Restricted / Read-Only Filesystems**: Environments that mount `/tmp` with `noexec`, strict container runtimes, Android/GraalVM native images without JNI support, or security managers blocking C library loading will prevent native PQC initialization. +Google Cloud HTTP/JSON client libraries support **Mutual TLS (mTLS)** client certificate authentication alongside PQC hybrid key exchange. -3. **Graceful Fallback Behavior**: - When native C libraries fail to load for either transport, the client libraries safely fall back to standard JDK JSSE: - ``` - WARNING: Conscrypt native libraries not available. Falling back to JDK TLS. - java.lang.UnsatisfiedLinkError: ... libc.so.6: version `GLIBC_2.35' not found - ``` - The client will continue operating using classical TLS provided by the JDK. +- When mTLS is enabled (via `GOOGLE_API_USE_CLIENT_CERTIFICATE="true"` in the system environment or via an explicit `MtlsProvider`), `InstantiatingHttpJsonChannelProvider` configures client certificate keystores and server trust stores. +- The trust manager factory is automatically initialized using the PKIX trust manager (`TrustManagerFactory.getInstance("PKIX", conscryptProvider)`), ensuring seamless compatibility with Conscrypt's TLS 1.3 engine and PQC named groups. --- -## Alternatives & How to Configure Them +## 8. Custom & Alternative Configurations -If you need to disable PQC, force classical key exchange, or use a custom TLS engine, you can configure alternative transport providers for both gRPC and HTTP/JSON. +If you need to disable PQC, force classical key exchange, bypass Conscrypt, or use a third-party security provider, you can customize the transport provider. -### Alternative 1: Forcing Classical (Non-PQC) Key Exchange (HTTP/JSON) +### Alternative 1: Forcing Classical (Non-PQC) Key Exchange -To explicitly force classical key exchange (such as `X25519` or `SecP256r1`) for HTTP/JSON clients: +To explicitly restrict key exchange to classical `X25519` (disabling post-quantum hybrid groups): ```java import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.gax.httpjson.HttpJsonConscryptUtils; import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; import org.conscrypt.Conscrypt; @@ -159,13 +175,13 @@ NetHttpTransport transport = // Explicitly offer only classical X25519 (disabling PQC hybrid groups) Conscrypt.setNamedGroups(socket, new String[] {"X25519"}); } catch (Exception e) { - // Handle or log socket configuration failure + // Ignore or log socket configuration failure } } }) .build(); -// Step 2: Build transport channel provider using custom transport +// Step 2: Build transport channel provider using the custom transport InstantiatingHttpJsonChannelProvider transportChannelProvider = SecretManagerServiceSettings.defaultHttpJsonTransportProviderBuilder() .setHttpTransport(transport) @@ -176,33 +192,15 @@ SecretManagerServiceSettings settings = SecretManagerServiceSettings.newHttpJsonBuilder() .setTransportChannelProvider(transportChannelProvider) .build(); -``` - -### Alternative 2: Forcing Classical (Non-PQC) Key Exchange (gRPC) - -For gRPC clients, you can configure `InstantiatingGrpcChannelProvider` with custom Netty SSL context options to restrict key exchange groups: - -```java -import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; -import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; -InstantiatingGrpcChannelProvider transportChannelProvider = - SecretManagerServiceSettings.defaultGrpcTransportProviderBuilder() - .setChannelConfigurator( - managedChannelBuilder -> { - // Custom channel configuration to override SSL/TLS settings - }) - .build(); - -SecretManagerServiceSettings settings = - SecretManagerServiceSettings.newBuilder() - .setTransportChannelProvider(transportChannelProvider) - .build(); +try (SecretManagerServiceClient client = SecretManagerServiceClient.create(settings)) { + // Client communicates using classical X25519 TLS 1.3 +} ``` -### Alternative 3: Bypassing Conscrypt to Use Standard JDK JSSE (HTTP/JSON) +### Alternative 2: Bypassing Conscrypt to Use Standard JDK JSSE -If you prefer to bypass Conscrypt completely and use the standard JDK JSSE provider: +To bypass Conscrypt completely and use the standard JDK JSSE TLS provider: ```java import com.google.api.client.http.javanet.NetHttpTransport; @@ -210,7 +208,7 @@ import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; -// Build standard NetHttpTransport without Conscrypt configuration +// Build a standard NetHttpTransport without GAX Conscrypt configuration NetHttpTransport standardTransport = new NetHttpTransport.Builder().build(); InstantiatingHttpJsonChannelProvider transportProvider = @@ -224,30 +222,35 @@ SecretManagerServiceSettings settings = .build(); try (SecretManagerServiceClient client = SecretManagerServiceClient.create(settings)) { - // Client uses standard JDK JSSE TLS + // Client communicates using standard JDK JSSE TLS } ``` -### Alternative 4: Configuring Custom Security Providers (e.g., Bouncy Castle) +### Alternative 3: Configuring Custom Security Providers (Locally Scoped to `NetHttpTransport`) -To use a third-party Security Provider (such as Bouncy Castle) for TLS: +If your application requires a custom cryptographic provider (such as Bouncy Castle), you can configure it **locally on the specific `NetHttpTransport` instance without modifying the global JVM `Security` provider table**: ```java import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; +import java.security.KeyStore; import java.security.Provider; -import java.security.Security; import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; -// Register custom provider +// Step 1: Instantiate custom security provider (without calling Security.addProvider globally) Provider customProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider(); -Security.addProvider(customProvider); -// Initialize custom SSLContext +// Step 2: Initialize TrustManagerFactory and SSLContext locally using customProvider +TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", customProvider); +tmf.init((KeyStore) null); // Loads standard JDK cacerts trust store + SSLContext sslContext = SSLContext.getInstance("TLS", customProvider); -sslContext.init(null, null, null); +sslContext.init(null, tmf.getTrustManagers(), null); -// Configure transport builder with custom SSLSocketFactory +// Step 3: Configure NetHttpTransport to use the locally scoped SSLSocketFactory NetHttpTransport customTransport = new NetHttpTransport.Builder() .setSslSocketFactory(sslContext.getSocketFactory()) @@ -257,25 +260,26 @@ InstantiatingHttpJsonChannelProvider transportProvider = SecretManagerServiceSettings.defaultHttpJsonTransportProviderBuilder() .setHttpTransport(customTransport) .build(); -``` - ---- -## Future Roadmap: JDK 27+ and Native JDK PQC Support +SecretManagerServiceSettings settings = + SecretManagerServiceSettings.newHttpJsonBuilder() + .setTransportChannelProvider(transportProvider) + .build(); -As quantum-resistant cryptography standards mature, Java is incorporating native PQC support directly into standard OpenJDK distributions. +try (SecretManagerServiceClient client = SecretManagerServiceClient.create(settings)) { + // Client communicates using Bouncy Castle TLS scoped strictly to this transport +} +``` -> [!IMPORTANT] -> **JDK 27+ Native PQC Support**: -> Starting with JDK 27, standard JDK Security Providers (SunJSSE) will include native support for NIST post-quantum key encapsulation standards (JEP / ML-KEM). +--- -### What JDK 27+ Means for Java SDK Users +## 9. Future Roadmap -1. **Zero-Dependency Native PQC**: - On JDK 27 and future Java LTS releases, applications running standard OpenJDK will automatically negotiate PQC key exchange natively out-of-the-box—even without Conscrypt or JNI native dependencies. +### gRPC Client Library Support +Out-of-the-box PQC support for gRPC client libraries (`gax-grpc`) is under active development and will be detailed in an upcoming release. -2. **Forward Compatibility**: - The GAX transport layer (`gax-grpc` and `gax-httpjson`) is designed so that when running on JDK 27+: - - If native BoringSSL libraries (Conscrypt / Netty-tcnative) are present, they continue to offer hardware-accelerated PQC key exchange. - - If native libraries are absent or disabled, the JDK's standard JSSE provider natively offers ML-KEM PQC key exchange. - - Applications do not need to make any code or configuration changes when upgrading to JDK 27+. +### JDK 27+ Native JDK PQC Support +As quantum-resistant cryptography standards mature, OpenJDK is incorporating native PQC support directly into standard Java releases: +- Starting with **JDK 27**, standard JDK Security Providers (`SunJSSE`) will include native support for NIST post-quantum key encapsulation standards (JEP / ML-KEM). +- When running on JDK 27+, Java applications will automatically negotiate ML-KEM PQC key exchange out-of-the-box—without requiring Conscrypt or JNI native dependencies. +- No code or configuration changes will be required in Google Cloud Java client libraries when upgrading to JDK 27+. From a2be78789fafe6118c1dee36bf1e7b8a14396892 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 30 Jul 2026 16:58:15 +0000 Subject: [PATCH 3/6] docs: remove mTLS/gRPC references, add default algorithms and fallback flow, and format JDK 27 as addendum --- docs/post_quantum_cryptography_guide.md | 65 ++++++++++++++----------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/docs/post_quantum_cryptography_guide.md b/docs/post_quantum_cryptography_guide.md index 3c6404806d0c..4c3b36db468b 100644 --- a/docs/post_quantum_cryptography_guide.md +++ b/docs/post_quantum_cryptography_guide.md @@ -23,9 +23,6 @@ To mitigate this threat immediately without sacrificing present-day security, Go PQC support is **enabled by default** for **HTTP/JSON** (REST) transport in Google Cloud Java client libraries (`gax-httpjson`) whenever native Conscrypt / BoringSSL libraries are supported on the runtime environment. -> [!NOTE] -> This guide currently focuses on **HTTP/JSON (`gax-httpjson`)** client libraries. Support for gRPC (`gax-grpc`) is under active development and will be detailed in an upcoming release. - ### Transport Support Summary | Transport | GAX Module | Underlying HTTP Client | Cryptographic Engine | PQC Activation | @@ -75,9 +72,30 @@ PQC enablement for REST/HTTP transport relies on architecture enhancements in `g - This allows GAX to inject an explicit cryptographic `Provider` and configure raw `SSLSocket` instances created by standard Java `HttpsURLConnection`. 2. **GAX Conscrypt Registration (`HttpJsonConscryptUtils`)**: - `InstantiatingHttpJsonChannelProvider` automatically invokes `HttpJsonConscryptUtils.configureConscryptSecurityProvider(builder)`. - - This registers Conscrypt as the socket provider and attaches a socket configurator that enables BoringSSL engine sockets (`Conscrypt.setUseEngineSocket(socket, true)`) and prefers hybrid PQC groups (`Conscrypt.setNamedGroups(socket, new String[] {"X25519MLKEM768", ...})`). -3. **TLS 1.3 Handshake Negotiation**: - - When HTTP connections are established, Conscrypt advertises `X25519MLKEM768` to Google Cloud endpoints, establishing a quantum-resistant TLS 1.3 channel. + - This registers Conscrypt as the socket provider and attaches a socket configurator that enables BoringSSL engine sockets (`Conscrypt.setUseEngineSocket(socket, true)`). + +### Default Algorithms & Multi-Algorithm Fallback Mechanism + +To maximize compatibility across diverse server endpoints and connect to as many algorithms as possible, `gax-httpjson` configures Conscrypt to advertise a comprehensive ordered list of **post-quantum hybrid groups, standalone PQC groups, and standard classical ECDH groups** by default: + +- **PQC / Hybrid Groups Offered by Default**: + - `X25519MLKEM768` + - `SecP256r1MLKEM768` + - `X25519Kyber768Draft00` + - `MLKEM1024` +- **Classical ECDH Groups Offered by Default**: + - `X25519` + - `SecP256r1` + - `SecP384r1` + - `SecP521r1` + +#### Two-Tier Fallback Architecture for Maximum Interoperability +1. **TLS 1.3 Handshake Negotiation (Algorithm Fallback)**: + - When a TLS 1.3 handshake begins, the client includes all default PQC and classical groups in its `supported_groups` ClientHello extension. + - **PQC-Enabled Endpoints**: If the server endpoint supports PQC (such as Google Cloud Front End endpoints), it selects `X25519MLKEM768` (or another mutually supported hybrid group), establishing an authenticated post-quantum session. + - **Non-PQC Endpoints**: If the server endpoint does not support post-quantum algorithms, it ignores the unknown PQC group identifiers and gracefully selects the highest-preference classical group (such as `X25519` or `SecP256r1`) without dropping the connection. +2. **Runtime Platform Fallback (Provider Fallback)**: + - If the runtime platform itself cannot load native Conscrypt libraries, `gax-httpjson` safely catches the error, logs a concise warning, and falls back to standard JDK JSSE (`SunJSSE`), ensuring network connectivity is never broken. ``` +-------------------------------------------------------------------+ @@ -92,7 +110,11 @@ PQC enablement for REST/HTTP transport relies on architecture enhancements in `g | | v v google-http-client uses Conscrypt Falls back to JDK JSSE - Offers X25519MLKEM768 (PQC Hybrid) Offers Classical X25519 + Offers PQC Hybrid + Classical Groups Offers Standard JDK Classical Groups + - Negotiates X25519MLKEM768 if server - Negotiates Classical X25519 / + supports PQC SecP256r1 via JDK TLS + - Automatically falls back to classical + X25519 if server lacks PQC ``` --- @@ -109,9 +131,9 @@ Conscrypt provides high-performance TLS and cryptographic operations by wrapping | Named Group Identifier | Description | Status in Conscrypt | | :--- | :--- | :--- | | **`X25519MLKEM768`** | Primary hybrid group combining X25519 ECDH with NIST FIPS 203 ML-KEM-768. | Recommended / Offered by Default | -| **`SecP256r1MLKEM768`** | Hybrid group combining NIST P-256 (`secp256r1`) with ML-KEM-768. | Supported | -| **`X25519Kyber768Draft00`** | Pre-standardization draft hybrid group combining X25519 with Kyber-768. | Legacy / Backward compatible | -| **`MLKEM1024`** | Standalone high-security post-quantum key encapsulation mechanism. | Supported | +| **`SecP256r1MLKEM768`** | Hybrid group combining NIST P-256 (`secp256r1`) with ML-KEM-768. | Supported / Offered by Default | +| **`X25519Kyber768Draft00`** | Pre-standardization draft hybrid group combining X25519 with Kyber-768. | Legacy / Offered for backward compatibility | +| **`MLKEM1024`** | Standalone high-security post-quantum key encapsulation mechanism. | Supported / Offered by Default | ### Supported Classical (Non-PQC) Groups @@ -140,16 +162,7 @@ Because Conscrypt relies on C native shared libraries (`conscrypt-openjdk-uber`) --- -## 7. Mutual TLS (mTLS) Support with PQC - -Google Cloud HTTP/JSON client libraries support **Mutual TLS (mTLS)** client certificate authentication alongside PQC hybrid key exchange. - -- When mTLS is enabled (via `GOOGLE_API_USE_CLIENT_CERTIFICATE="true"` in the system environment or via an explicit `MtlsProvider`), `InstantiatingHttpJsonChannelProvider` configures client certificate keystores and server trust stores. -- The trust manager factory is automatically initialized using the PKIX trust manager (`TrustManagerFactory.getInstance("PKIX", conscryptProvider)`), ensuring seamless compatibility with Conscrypt's TLS 1.3 engine and PQC named groups. - ---- - -## 8. Custom & Alternative Configurations +## 7. Custom & Alternative Configurations If you need to disable PQC, force classical key exchange, bypass Conscrypt, or use a third-party security provider, you can customize the transport provider. @@ -273,13 +286,9 @@ try (SecretManagerServiceClient client = SecretManagerServiceClient.create(setti --- -## 9. Future Roadmap - -### gRPC Client Library Support -Out-of-the-box PQC support for gRPC client libraries (`gax-grpc`) is under active development and will be detailed in an upcoming release. +## 8. Addendum: JDK 27+ and Native OpenJDK PQC Support -### JDK 27+ Native JDK PQC Support As quantum-resistant cryptography standards mature, OpenJDK is incorporating native PQC support directly into standard Java releases: -- Starting with **JDK 27**, standard JDK Security Providers (`SunJSSE`) will include native support for NIST post-quantum key encapsulation standards (JEP / ML-KEM). -- When running on JDK 27+, Java applications will automatically negotiate ML-KEM PQC key exchange out-of-the-box—without requiring Conscrypt or JNI native dependencies. -- No code or configuration changes will be required in Google Cloud Java client libraries when upgrading to JDK 27+. +- Starting with **JDK 27**, standard JDK Security Providers (`SunJSSE`) include native support for NIST post-quantum key encapsulation standards (JEP / ML-KEM). +- When running on JDK 27 or later, Java applications automatically negotiate ML-KEM PQC key exchange out-of-the-box—without requiring Conscrypt or JNI native dependencies. +- No code or configuration changes are required in Google Cloud Java client libraries when running on JDK 27+. From cd1d649c056ea9f54ac7d1bf13e702d7cf3301db Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 30 Jul 2026 17:24:15 +0000 Subject: [PATCH 4/6] docs: refine HTTP/JSON PQC guide with exact versions, concise intro, and custom provider builder examples --- docs/post_quantum_cryptography_guide.md | 133 +++++++++--------------- 1 file changed, 50 insertions(+), 83 deletions(-) diff --git a/docs/post_quantum_cryptography_guide.md b/docs/post_quantum_cryptography_guide.md index 4c3b36db468b..66e63f9be25e 100644 --- a/docs/post_quantum_cryptography_guide.md +++ b/docs/post_quantum_cryptography_guide.md @@ -2,20 +2,11 @@ ## 1. The Quantum Threat & Why PQC is Critical -### The Problem: Store-Now, Decrypt-Later (SNDL) Attacks -Traditional Transport Layer Security (TLS) relies on classical asymmetric public-key cryptography—such as RSA, Elliptic Curve Diffie-Hellman (`ECDH`), and `X25519`—to establish secure encrypted connections. While these classical algorithms are computationally secure against present-day classical computers, they are vulnerable to **Shor's algorithm** running on a cryptographically relevant quantum computer (CRQC). +Traditional TLS public-key encryption (such as RSA and ECDH) is vulnerable to future decryption by quantum computers. -An adversary does not need to wait for a quantum computer to be built before attacking classical encryption: -- **Harvest Now, Decrypt Later**: Threat actors can intercept and store encrypted TLS network traffic today. -- **Future Decryption**: Once a sufficiently powerful quantum computer becomes operational, adversaries will be able to retroactively break the classical Diffie-Hellman key exchange and decrypt long-lived confidential data collected years earlier. - -### The Consequence of Not Using PQC -Without Post-Quantum Cryptography (PQC), any sensitive data transmitted across networks today—including authentication credentials, financial records, proprietary algorithms, and customer data—remains vulnerable to retroactive decryption in the future. - -### The Solution: Hybrid PQC Key Exchange -To mitigate this threat immediately without sacrificing present-day security, Google Cloud HTTP/JSON Java client libraries support **Hybrid PQC Key Exchange**. -- A hybrid key exchange combines a classical ECDH algorithm (such as `X25519`) with a NIST-standardized Post-Quantum Key Encapsulation Mechanism (KEM), such as **ML-KEM-768** (FIPS 203), negotiated as `X25519MLKEM768`. -- This ensures that your communications remain at least as secure as standard classical TLS 1.3 against present-day attacks, while simultaneously protecting encrypted sessions against future quantum decryption. +- **The Risk ("Store-Now, Decrypt-Later")**: Adversaries can intercept and store encrypted network traffic today with the intent to decrypt it once cryptographically relevant quantum computers become available. +- **The Consequence**: Without Post-Quantum Cryptography (PQC), sensitive data transmitted today—such as credentials, financial records, and customer data—is at risk of retroactive decryption in the future. +- **The Solution (Hybrid PQC)**: Google Cloud HTTP/JSON Java client libraries support **Hybrid PQC Key Exchange** (such as `X25519MLKEM768`), combining a classical ECDH algorithm (like `X25519`) with a NIST-standardized Post-Quantum Key Encapsulation Mechanism (like `ML-KEM-768`, FIPS 203). This protects encrypted traffic against both present-day and future quantum threats without sacrificing existing security. --- @@ -31,9 +22,9 @@ PQC support is **enabled by default** for **HTTP/JSON** (REST) transport in Goog --- -## 3. How to Verify That You Are Using PQC +## 3. How to Verify That You Are Using PQC in Google Cloud Java Client Libraries -You can verify that your HTTP/JSON client library is actively negotiating Post-Quantum Cryptography through operational logs, debug logging, or network traffic analysis. +You can verify that your Google Cloud HTTP/JSON Java client library is actively negotiating Post-Quantum Cryptography through operational logs, debug logging, or network traffic analysis. ### 1. Check Operational Log Messages When Conscrypt initializes successfully and configures PQC named groups, **no warning logs are emitted**. @@ -57,45 +48,34 @@ To inspect the exact initialization status and any underlying native library loa ``` ### 3. Packet & Handshake Inspection -During a TLS 1.3 handshake with Google Front End (GFE) services, you can verify PQC negotiation using network analysis tools (such as Wireshark or OpenSSL `s_client`): +During a TLS 1.3 handshake with Google Front End (GFE) services, you can verify PQC negotiation by inspecting the handshake packets: - **ClientHello**: Inspect the TLS `supported_groups` extension (Extension 10). When PQC is active, `X25519MLKEM768` (Group ID `0x4543` / `17731` or standardized IANA PQC identifier) is advertised in the ClientHello. - **ServerHello**: The GFE endpoint selects `X25519MLKEM768` in the `key_share` extension, confirming that hybrid post-quantum key agreement was established for the connection. --- -## 4. HTTP/JSON Transport Implementation Details (`gax-httpjson` & `google-http-java-client`) +## 4. Architecture & Minimum Required Versions -PQC enablement for REST/HTTP transport relies on architecture enhancements in `google-http-java-client` and `gax-httpjson`: +PQC enablement for HTTP/JSON transport requires compatible versions of `gax-httpjson` and `google-http-client`: -1. **`NetHttpTransport.Builder` API Enhancements**: - - `NetHttpTransport.Builder` provides `.setSecurityProvider(Provider)` and `.setSslSocketConfigurator(SslSocketConfigurator)`. - - This allows GAX to inject an explicit cryptographic `Provider` and configure raw `SSLSocket` instances created by standard Java `HttpsURLConnection`. -2. **GAX Conscrypt Registration (`HttpJsonConscryptUtils`)**: - - `InstantiatingHttpJsonChannelProvider` automatically invokes `HttpJsonConscryptUtils.configureConscryptSecurityProvider(builder)`. - - This registers Conscrypt as the socket provider and attaches a socket configurator that enables BoringSSL engine sockets (`Conscrypt.setUseEngineSocket(socket, true)`). +> [!TIP] +> **Recommended BOM**: +> We recommend importing Google Cloud Java libraries using **`libraries-bom` version `26.86.0+`**, which automatically manages compatible dependency versions across all Google Cloud client libraries, GAX, and the Google HTTP Client. -### Default Algorithms & Multi-Algorithm Fallback Mechanism +### Minimum Required Versions + +| Library | Minimum Required Version | Role | +| :--- | :--- | :--- | +| **`gax-httpjson`** | `2.83.0+` | Automatically registers Conscrypt as the TLS security provider and configures PQC named groups. | +| **`google-http-client`** | `2.2.0+` | Provides security provider registration and socket configurators on `NetHttpTransport.Builder`. | -To maximize compatibility across diverse server endpoints and connect to as many algorithms as possible, `gax-httpjson` configures Conscrypt to advertise a comprehensive ordered list of **post-quantum hybrid groups, standalone PQC groups, and standard classical ECDH groups** by default: +### How GAX and Google Cloud Servers Work Together -- **PQC / Hybrid Groups Offered by Default**: - - `X25519MLKEM768` - - `SecP256r1MLKEM768` - - `X25519Kyber768Draft00` - - `MLKEM1024` -- **Classical ECDH Groups Offered by Default**: - - `X25519` - - `SecP256r1` - - `SecP384r1` - - `SecP521r1` +When you construct a Google Cloud HTTP/JSON service client, `gax-httpjson` automatically registers Conscrypt as the underlying cryptographic provider on the Google HTTP Client (`NetHttpTransport`). -#### Two-Tier Fallback Architecture for Maximum Interoperability -1. **TLS 1.3 Handshake Negotiation (Algorithm Fallback)**: - - When a TLS 1.3 handshake begins, the client includes all default PQC and classical groups in its `supported_groups` ClientHello extension. - - **PQC-Enabled Endpoints**: If the server endpoint supports PQC (such as Google Cloud Front End endpoints), it selects `X25519MLKEM768` (or another mutually supported hybrid group), establishing an authenticated post-quantum session. - - **Non-PQC Endpoints**: If the server endpoint does not support post-quantum algorithms, it ignores the unknown PQC group identifiers and gracefully selects the highest-preference classical group (such as `X25519` or `SecP256r1`) without dropping the connection. -2. **Runtime Platform Fallback (Provider Fallback)**: - - If the runtime platform itself cannot load native Conscrypt libraries, `gax-httpjson` safely catches the error, logs a concise warning, and falls back to standard JDK JSSE (`SunJSSE`), ensuring network connectivity is never broken. +- **Negotiation with Google Cloud Servers**: During the TLS 1.3 handshake, `gax-httpjson` advertises Post-Quantum Cryptography named groups (`X25519MLKEM768`, etc.) in preference order alongside classical TLS groups. When connecting to Google Cloud Front End (GFE) endpoints, the server evaluates the client's list from top to bottom and **selects the first compatible algorithm from the list that it also supports**—in this case, `X25519MLKEM768` (#1 preference), establishing an authenticated post-quantum session. +- **Transparent Endpoint Compatibility**: When connecting to endpoints that do not yet support PQC, the server skips the unknown post-quantum identifiers at the top of the list and selects **the first compatible algorithm from the client's list that it recognizes** (such as classical `X25519`), transparently negotiating standard TLS without dropping the connection. +- **Platform Runtime Fallback**: If the runtime environment cannot load native Conscrypt libraries, `gax-httpjson` catches the error, logs a concise warning, and falls back to standard JDK JSSE (`SunJSSE`), ensuring network connectivity is never broken. ``` +-------------------------------------------------------------------+ @@ -111,37 +91,29 @@ To maximize compatibility across diverse server endpoints and connect to as many v v google-http-client uses Conscrypt Falls back to JDK JSSE Offers PQC Hybrid + Classical Groups Offers Standard JDK Classical Groups - - Negotiates X25519MLKEM768 if server - Negotiates Classical X25519 / - supports PQC SecP256r1 via JDK TLS - - Automatically falls back to classical - X25519 if server lacks PQC + - Server selects 1st compatible group - Server negotiates Classical + - Negotiates X25519MLKEM768 on - Negotiates Classical X25519 / + Google Cloud Front End (GFE) secp256r1 via JDK TLS + - Automatically falls back to X25519 + on older non-PQC servers ``` --- -## 5. Conscrypt Capabilities & Supported Algorithms +## 5. Supported Key Exchange Groups -Conscrypt provides high-performance TLS and cryptographic operations by wrapping BoringSSL via JNI native libraries. +Google Cloud HTTP/JSON client libraries configure Conscrypt to advertise the following named groups in preference order: -> [!NOTE] -> For a full listing of named groups and capabilities supported across Conscrypt versions, refer to the official [Conscrypt Capabilities Documentation](https://github.com/google/conscrypt/blob/2.6.0/CAPABILITIES.md#supported-named-groups). - -### Supported PQC & Hybrid Key Exchange Groups - -| Named Group Identifier | Description | Status in Conscrypt | -| :--- | :--- | :--- | -| **`X25519MLKEM768`** | Primary hybrid group combining X25519 ECDH with NIST FIPS 203 ML-KEM-768. | Recommended / Offered by Default | -| **`SecP256r1MLKEM768`** | Hybrid group combining NIST P-256 (`secp256r1`) with ML-KEM-768. | Supported / Offered by Default | -| **`X25519Kyber768Draft00`** | Pre-standardization draft hybrid group combining X25519 with Kyber-768. | Legacy / Offered for backward compatibility | -| **`MLKEM1024`** | Standalone high-security post-quantum key encapsulation mechanism. | Supported / Offered by Default | +1. `X25519MLKEM768` +2. `SecP256r1MLKEM768` +3. `MLKEM1024` +4. `MLKEM768` +5. `X25519Kyber768Draft00` *(deprecated draft group kept for backward compatibility)* +6. `X25519` +7. `secp256r1` +8. `secp384r1` -### Supported Classical (Non-PQC) Groups - -For environments or endpoints where PQC key exchange is disabled or unsupported, Conscrypt falls back to standard classical named groups: -- `X25519` (Curve25519 ECDH) -- `SecP256r1` (NIST P-256 ECDH) -- `SecP384r1` (NIST P-384 ECDH) -- `SecP521r1` (NIST P-521 ECDH) +For additional details on Conscrypt's cryptographic algorithms and capabilities, refer to the official [Conscrypt CAPABILITIES.md](https://github.com/google/conscrypt/blob/2.6.0/CAPABILITIES.md#supported-named-groups). --- @@ -239,36 +211,31 @@ try (SecretManagerServiceClient client = SecretManagerServiceClient.create(setti } ``` -### Alternative 3: Configuring Custom Security Providers (Locally Scoped to `NetHttpTransport`) +### Alternative 3: Configuring Custom Security Providers -If your application requires a custom cryptographic provider (such as Bouncy Castle), you can configure it **locally on the specific `NetHttpTransport` instance without modifying the global JVM `Security` provider table**: +If your application requires a custom cryptographic provider (such as Bouncy Castle), you can configure it on a specific `NetHttpTransport` instance using `NetHttpTransport.Builder.setSecurityProvider(...)` and `.setSslSocketConfigurator(...)`: ```java import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; -import java.security.KeyStore; import java.security.Provider; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; -// Step 1: Instantiate custom security provider (without calling Security.addProvider globally) +// Step 1: Instantiate custom security provider Provider customProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider(); -// Step 2: Initialize TrustManagerFactory and SSLContext locally using customProvider -TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", customProvider); -tmf.init((KeyStore) null); // Loads standard JDK cacerts trust store - -SSLContext sslContext = SSLContext.getInstance("TLS", customProvider); -sslContext.init(null, tmf.getTrustManagers(), null); - -// Step 3: Configure NetHttpTransport to use the locally scoped SSLSocketFactory +// Step 2: Configure NetHttpTransport with custom security provider and SSLSocketConfigurator NetHttpTransport customTransport = new NetHttpTransport.Builder() - .setSslSocketFactory(sslContext.getSocketFactory()) + .setSecurityProvider(customProvider) + .setSslSocketConfigurator( + socket -> { + // Configure custom SSLSocket options (e.g., cipher suites, protocols, or named groups) + }) .build(); +// Step 3: Build transport provider and service client InstantiatingHttpJsonChannelProvider transportProvider = SecretManagerServiceSettings.defaultHttpJsonTransportProviderBuilder() .setHttpTransport(customTransport) @@ -280,7 +247,7 @@ SecretManagerServiceSettings settings = .build(); try (SecretManagerServiceClient client = SecretManagerServiceClient.create(settings)) { - // Client communicates using Bouncy Castle TLS scoped strictly to this transport + // Client communicates using custom security provider scoped strictly to this transport } ``` From ea666427d836d26cd0abb35f48d4247ea4dd9a74 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 30 Jul 2026 17:46:35 +0000 Subject: [PATCH 5/6] docs: reorganize HTTP/JSON PQC guide with versions first and clarify JDK 27 addendum scope --- docs/post_quantum_cryptography_guide.md | 115 +++++++++++------------- 1 file changed, 51 insertions(+), 64 deletions(-) diff --git a/docs/post_quantum_cryptography_guide.md b/docs/post_quantum_cryptography_guide.md index 66e63f9be25e..7f607e683cc1 100644 --- a/docs/post_quantum_cryptography_guide.md +++ b/docs/post_quantum_cryptography_guide.md @@ -10,72 +10,39 @@ Traditional TLS public-key encryption (such as RSA and ECDH) is vulnerable to fu --- -## 2. Overview & Default Behavior in `gax-httpjson` +## 2. HTTP/JSON (REST) Client Library Support -PQC support is **enabled by default** for **HTTP/JSON** (REST) transport in Google Cloud Java client libraries (`gax-httpjson`) whenever native Conscrypt / BoringSSL libraries are supported on the runtime environment. +Post-Quantum Cryptography is **enabled by default** for **HTTP/JSON** (REST) transport in Google Cloud Java client libraries (`gax-httpjson`) whenever native Conscrypt / BoringSSL libraries are supported on the runtime environment. -### Transport Support Summary +### 2.1 Minimum Required Versions -| Transport | GAX Module | Underlying HTTP Client | Cryptographic Engine | PQC Activation | -| :--- | :--- | :--- | :--- | :--- | -| **HTTP/JSON** | `gax-httpjson` | Google HTTP Client (`NetHttpTransport`) | Conscrypt (BoringSSL JNI) | **Enabled by Default** via `google-http-java-client` security provider API | - ---- - -## 3. How to Verify That You Are Using PQC in Google Cloud Java Client Libraries - -You can verify that your Google Cloud HTTP/JSON Java client library is actively negotiating Post-Quantum Cryptography through operational logs, debug logging, or network traffic analysis. - -### 1. Check Operational Log Messages -When Conscrypt initializes successfully and configures PQC named groups, **no warning logs are emitted**. - -If your environment cannot load native Conscrypt libraries or cannot configure PQC groups, the library emits a concise, one-line warning at `Level.WARNING` and safely falls back to standard JDK TLS: -``` -WARNING: Conscrypt native libraries not available. Falling back to JDK TLS. -``` -If you **do not see this warning message** in your application logs, Conscrypt has successfully initialized and enabled PQC key exchange. - -### 2. Enable Debug Logging (`Level.FINE`) -To inspect the exact initialization status and any underlying native library loader exceptions, enable debug logging (`Level.FINE`) for `com.google.api.gax.httpjson.HttpJsonConscryptUtils`: - -- In `logging.properties`: - ```properties - com.google.api.gax.httpjson.HttpJsonConscryptUtils.level = FINE - ``` -- If an error occurs during initialization, the full exception stacktrace (`UnsatisfiedLinkError`, `LinkageError`, etc.) will appear only at `FINE` level: - ``` - FINE: Conscrypt initialization failed with exception: java.lang.UnsatisfiedLinkError: ... - ``` - -### 3. Packet & Handshake Inspection -During a TLS 1.3 handshake with Google Front End (GFE) services, you can verify PQC negotiation by inspecting the handshake packets: -- **ClientHello**: Inspect the TLS `supported_groups` extension (Extension 10). When PQC is active, `X25519MLKEM768` (Group ID `0x4543` / `17731` or standardized IANA PQC identifier) is advertised in the ClientHello. -- **ServerHello**: The GFE endpoint selects `X25519MLKEM768` in the `key_share` extension, confirming that hybrid post-quantum key agreement was established for the connection. - ---- - -## 4. Architecture & Minimum Required Versions - -PQC enablement for HTTP/JSON transport requires compatible versions of `gax-httpjson` and `google-http-client`: +PQC enablement for HTTP/JSON transport requires compatible versions of `conscrypt-openjdk-uber`, `gax-httpjson`, and `google-http-client`: > [!TIP] > **Recommended BOM**: > We recommend importing Google Cloud Java libraries using **`libraries-bom` version `26.86.0+`**, which automatically manages compatible dependency versions across all Google Cloud client libraries, GAX, and the Google HTTP Client. -### Minimum Required Versions - | Library | Minimum Required Version | Role | | :--- | :--- | :--- | +| **`conscrypt-openjdk-uber`** | `2.6.0+` | Provides BoringSSL native C engine and TLS 1.3 PQC hybrid named groups. | | **`gax-httpjson`** | `2.83.0+` | Automatically registers Conscrypt as the TLS security provider and configures PQC named groups. | | **`google-http-client`** | `2.2.0+` | Provides security provider registration and socket configurators on `NetHttpTransport.Builder`. | -### How GAX and Google Cloud Servers Work Together +### 2.2 Why Conscrypt? -When you construct a Google Cloud HTTP/JSON service client, `gax-httpjson` automatically registers Conscrypt as the underlying cryptographic provider on the Google HTTP Client (`NetHttpTransport`). +Standard Java Development Kits (JDK 8, 11, 17, and 21) do not natively support Post-Quantum Cryptography in their built-in TLS providers (`SunJSSE`). While native ML-KEM support is planned for **JDK 27+**, requiring all users to upgrade to JDK 27 is not feasible for most production environments. -- **Negotiation with Google Cloud Servers**: During the TLS 1.3 handshake, `gax-httpjson` advertises Post-Quantum Cryptography named groups (`X25519MLKEM768`, etc.) in preference order alongside classical TLS groups. When connecting to Google Cloud Front End (GFE) endpoints, the server evaluates the client's list from top to bottom and **selects the first compatible algorithm from the list that it also supports**—in this case, `X25519MLKEM768` (#1 preference), establishing an authenticated post-quantum session. -- **Transparent Endpoint Compatibility**: When connecting to endpoints that do not yet support PQC, the server skips the unknown post-quantum identifiers at the top of the list and selects **the first compatible algorithm from the client's list that it recognizes** (such as classical `X25519`), transparently negotiating standard TLS without dropping the connection. -- **Platform Runtime Fallback**: If the runtime environment cannot load native Conscrypt libraries, `gax-httpjson` catches the error, logs a concise warning, and falls back to standard JDK JSSE (`SunJSSE`), ensuring network connectivity is never broken. +We chose **Conscrypt** (`conscrypt-openjdk-uber`) because: +1. **Maximum Java & OS Compatibility**: Conscrypt wraps Google's BoringSSL cryptographic engine via JNI, enabling quantum-resistant TLS 1.3 handshakes across existing Java LTS runtimes (Java 8, 11, 17, 21, and 25). +2. **Zero Runtime Configuration Required**: By bundling Conscrypt as an optional dependency, `gax-httpjson` delivers high-performance PQC out-of-the-box without requiring users to replace their JVM or upgrade their JDK. + +### 2.3 How HTTP/JSON Clients and Google Cloud Servers Work Together + +When you construct a Google Cloud HTTP/JSON service client, `gax-httpjson` registers Conscrypt on the Google HTTP Client (`NetHttpTransport`) to advertise PQC and classical groups in preference order: + +- **PQC-Enabled Endpoints (GFE)**: During the TLS 1.3 handshake, Google Front End servers select `X25519MLKEM768` (#1 preference), establishing a quantum-resistant session. +- **Non-PQC Endpoints**: Endpoints that do not support PQC ignore unknown post-quantum identifiers and select the first compatible classical algorithm (such as `X25519`). +- **Platform Runtime Fallback**: If Conscrypt native libraries cannot load on the OS, the client logs a concise warning and falls back to standard JDK JSSE (`SunJSSE`). ``` +-------------------------------------------------------------------+ @@ -98,9 +65,7 @@ When you construct a Google Cloud HTTP/JSON service client, `gax-httpjson` autom on older non-PQC servers ``` ---- - -## 5. Supported Key Exchange Groups +### 2.4 Supported Key Exchange Groups Google Cloud HTTP/JSON client libraries configure Conscrypt to advertise the following named groups in preference order: @@ -115,9 +80,7 @@ Google Cloud HTTP/JSON client libraries configure Conscrypt to advertise the fol For additional details on Conscrypt's cryptographic algorithms and capabilities, refer to the official [Conscrypt CAPABILITIES.md](https://github.com/google/conscrypt/blob/2.6.0/CAPABILITIES.md#supported-named-groups). ---- - -## 6. Platform Compatibility & Native Library Limitations +### 2.5 Platform Compatibility & Native Library Limitations Because Conscrypt relies on C native shared libraries (`conscrypt-openjdk-uber`) loaded via Java Native Interface (JNI), PQC support depends on OS platform compatibility: @@ -132,13 +95,36 @@ Because Conscrypt relies on C native shared libraries (`conscrypt-openjdk-uber`) ``` - Your application will continue running normally using classical TLS provided by the JDK. ---- +### 2.6 Verifying PQC in HTTP/JSON Client Libraries + +You can verify that your Google Cloud HTTP/JSON Java client library is actively negotiating Post-Quantum Cryptography through operational logs or debug logging. Note that the log messages and logger categories below apply specifically to HTTP/JSON (REST) client libraries. + +#### 1. Check Operational Log Messages +When Conscrypt initializes successfully and configures PQC named groups, **no warning logs are emitted**. + +If your environment cannot load native Conscrypt libraries or cannot configure PQC groups, the library emits a concise, one-line warning at `Level.WARNING` and safely falls back to standard JDK TLS: +``` +WARNING: Conscrypt native libraries not available. Falling back to JDK TLS. +``` +If you **do not see this warning message** in your application logs, Conscrypt has successfully initialized and enabled PQC key exchange. + +#### 2. Enable Debug Logging (`Level.FINE`) +To inspect the exact initialization status and any underlying native library loader exceptions, enable debug logging (`Level.FINE`) for `com.google.api.gax.httpjson.HttpJsonConscryptUtils`: + +- In `logging.properties`: + ```properties + com.google.api.gax.httpjson.HttpJsonConscryptUtils.level = FINE + ``` +- If an error occurs during initialization, the full exception stacktrace (`UnsatisfiedLinkError`, `LinkageError`, etc.) will appear only at `FINE` level: + ``` + FINE: Conscrypt initialization failed with exception: java.lang.UnsatisfiedLinkError: ... + ``` -## 7. Custom & Alternative Configurations +### 2.7 Custom & Alternative Configurations If you need to disable PQC, force classical key exchange, bypass Conscrypt, or use a third-party security provider, you can customize the transport provider. -### Alternative 1: Forcing Classical (Non-PQC) Key Exchange +#### Alternative 1: Forcing Classical (Non-PQC) Key Exchange To explicitly restrict key exchange to classical `X25519` (disabling post-quantum hybrid groups): @@ -183,7 +169,7 @@ try (SecretManagerServiceClient client = SecretManagerServiceClient.create(setti } ``` -### Alternative 2: Bypassing Conscrypt to Use Standard JDK JSSE +#### Alternative 2: Bypassing Conscrypt to Use Standard JDK JSSE To bypass Conscrypt completely and use the standard JDK JSSE TLS provider: @@ -211,7 +197,7 @@ try (SecretManagerServiceClient client = SecretManagerServiceClient.create(setti } ``` -### Alternative 3: Configuring Custom Security Providers +#### Alternative 3: Configuring Custom Security Providers If your application requires a custom cryptographic provider (such as Bouncy Castle), you can configure it on a specific `NetHttpTransport` instance using `NetHttpTransport.Builder.setSecurityProvider(...)` and `.setSslSocketConfigurator(...)`: @@ -253,9 +239,10 @@ try (SecretManagerServiceClient client = SecretManagerServiceClient.create(setti --- -## 8. Addendum: JDK 27+ and Native OpenJDK PQC Support +## 3. Addendum: JDK 27+ and Native OpenJDK PQC Support As quantum-resistant cryptography standards mature, OpenJDK is incorporating native PQC support directly into standard Java releases: - Starting with **JDK 27**, standard JDK Security Providers (`SunJSSE`) include native support for NIST post-quantum key encapsulation standards (JEP / ML-KEM). -- When running on JDK 27 or later, Java applications automatically negotiate ML-KEM PQC key exchange out-of-the-box—without requiring Conscrypt or JNI native dependencies. +- **Google Cloud Java Client Libraries**: Google Cloud Java client SDKs use Conscrypt by default whenever it is available on the platform (delivering hardware-accelerated BoringSSL performance across all Java releases). +- **Your Own Applications**: For your own Java applications or non-Conscrypt HTTPS connections running on JDK 27 or later, standard OpenJDK Security Providers automatically negotiate ML-KEM PQC key exchange out-of-the-box—even without Conscrypt or JNI native dependencies. - No code or configuration changes are required in Google Cloud Java client libraries when running on JDK 27+. From 67661f5777b58723f55a3308fcca815557421ada Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 30 Jul 2026 20:28:00 +0000 Subject: [PATCH 6/6] docs: update PQC guide with debug-level logging and prominent WARNING callout on user responsibility --- docs/post_quantum_cryptography_guide.md | 48 ++++++++++++------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/docs/post_quantum_cryptography_guide.md b/docs/post_quantum_cryptography_guide.md index 7f607e683cc1..2c045378cffd 100644 --- a/docs/post_quantum_cryptography_guide.md +++ b/docs/post_quantum_cryptography_guide.md @@ -12,7 +12,11 @@ Traditional TLS public-key encryption (such as RSA and ECDH) is vulnerable to fu ## 2. HTTP/JSON (REST) Client Library Support -Post-Quantum Cryptography is **enabled by default** for **HTTP/JSON** (REST) transport in Google Cloud Java client libraries (`gax-httpjson`) whenever native Conscrypt / BoringSSL libraries are supported on the runtime environment. +Google Cloud Java client libraries (`gax-httpjson`) use **Conscrypt by default** to achieve Post-Quantum Cryptography (PQC) for **HTTP/JSON** (REST) transport whenever native BoringSSL libraries are supported on the runtime environment. + +> [!WARNING] +> **User Responsibility for Conscrypt Compatibility**: +> It is the user's responsibility to ensure that their runtime environment supports Conscrypt native libraries if they want to use the default PQC configuration. Otherwise, users can opt to use alternative configurations (see **Section 2.7**). If Conscrypt cannot be initialized, the client library will silently fall back to standard JDK JSSE (`SunJSSE`), which on Java 8–20 has no Post-Quantum Cryptography support. See **Section 2.5 (Known Conscrypt Compatibility Issues)** for more information. ### 2.1 Minimum Required Versions @@ -30,19 +34,19 @@ PQC enablement for HTTP/JSON transport requires compatible versions of `conscryp ### 2.2 Why Conscrypt? -Standard Java Development Kits (JDK 8, 11, 17, and 21) do not natively support Post-Quantum Cryptography in their built-in TLS providers (`SunJSSE`). While native ML-KEM support is planned for **JDK 27+**, requiring all users to upgrade to JDK 27 is not feasible for most production environments. +Standard Java Development Kits (Java 8–20) do not natively support Post-Quantum Cryptography in their built-in TLS providers (`SunJSSE`). While native ML-KEM support is planned for **JDK 27+**, requiring all users to upgrade to JDK 27 is not feasible for most production environments. -We chose **Conscrypt** (`conscrypt-openjdk-uber`) because: -1. **Maximum Java & OS Compatibility**: Conscrypt wraps Google's BoringSSL cryptographic engine via JNI, enabling quantum-resistant TLS 1.3 handshakes across existing Java LTS runtimes (Java 8, 11, 17, 21, and 25). +**Conscrypt** (`conscrypt-openjdk-uber`) is the default `SecurityProvider` for Google Cloud Java client libraries because: +1. **Maximum Java & OS Compatibility**: Conscrypt wraps Google's BoringSSL cryptographic engine via JNI, enabling quantum-resistant TLS 1.3 handshakes across existing Java runtimes (**Java 8+**). 2. **Zero Runtime Configuration Required**: By bundling Conscrypt as an optional dependency, `gax-httpjson` delivers high-performance PQC out-of-the-box without requiring users to replace their JVM or upgrade their JDK. ### 2.3 How HTTP/JSON Clients and Google Cloud Servers Work Together When you construct a Google Cloud HTTP/JSON service client, `gax-httpjson` registers Conscrypt on the Google HTTP Client (`NetHttpTransport`) to advertise PQC and classical groups in preference order: -- **PQC-Enabled Endpoints (GFE)**: During the TLS 1.3 handshake, Google Front End servers select `X25519MLKEM768` (#1 preference), establishing a quantum-resistant session. +- **PQC-Enabled Google Cloud Endpoints**: During the TLS 1.3 handshake, Google Cloud servers select `X25519MLKEM768` (#1 preference), establishing a quantum-resistant session. - **Non-PQC Endpoints**: Endpoints that do not support PQC ignore unknown post-quantum identifiers and select the first compatible classical algorithm (such as `X25519`). -- **Platform Runtime Fallback**: If Conscrypt native libraries cannot load on the OS, the client logs a concise warning and falls back to standard JDK JSSE (`SunJSSE`). +- **Platform Runtime Fallback**: If Conscrypt native libraries cannot load on the OS, the client logs at debug level (`FINE`) and falls back to standard JDK JSSE (`SunJSSE`) without emitting operational warnings. ``` +-------------------------------------------------------------------+ @@ -59,8 +63,8 @@ When you construct a Google Cloud HTTP/JSON service client, `gax-httpjson` regis google-http-client uses Conscrypt Falls back to JDK JSSE Offers PQC Hybrid + Classical Groups Offers Standard JDK Classical Groups - Server selects 1st compatible group - Server negotiates Classical - - Negotiates X25519MLKEM768 on - Negotiates Classical X25519 / - Google Cloud Front End (GFE) secp256r1 via JDK TLS + - Negotiates X25519MLKEM768 on X25519 / secp256r1 via JDK TLS + Google Cloud Endpoints - Automatically falls back to X25519 on older non-PQC servers ``` @@ -80,45 +84,37 @@ Google Cloud HTTP/JSON client libraries configure Conscrypt to advertise the fol For additional details on Conscrypt's cryptographic algorithms and capabilities, refer to the official [Conscrypt CAPABILITIES.md](https://github.com/google/conscrypt/blob/2.6.0/CAPABILITIES.md#supported-named-groups). -### 2.5 Platform Compatibility & Native Library Limitations +### 2.5 Known Conscrypt Compatibility Issues -Because Conscrypt relies on C native shared libraries (`conscrypt-openjdk-uber`) loaded via Java Native Interface (JNI), PQC support depends on OS platform compatibility: +Because Conscrypt relies on C native shared libraries (`conscrypt-openjdk-uber`) loaded via Java Native Interface (JNI), PQC support depends on OS platform compatibility. Note that the constraints below represent known common issues and are **not an exhaustive list** of Conscrypt platform requirements: 1. **System & GLIBC Compatibility Constraints**: - **Linux glibc Versioning**: Conscrypt native C binaries require compatible C runtime (`glibc`) versions (such as `GLIBC_2.35+`). Older Linux distributions or lightweight images (such as Alpine Linux using `musl` libc) will fail to load native libraries (`UnsatisfiedLinkError`). - **Restricted Filesystems**: Operating systems that mount `/tmp` with `noexec`, strict container security profiles, or environments blocking JNI library extraction will prevent Conscrypt from initializing. 2. **Graceful Fallback Behavior**: - - Whenever native library loading fails, `gax-httpjson` catches the error, logs a concise warning at `Level.WARNING`, and safely falls back to standard JDK JSSE: + - Whenever native library loading fails, `gax-httpjson` catches the error, logs at **`Level.FINE` (debug level)**, and safely falls back to standard JDK JSSE (`SunJSSE`): ``` - WARNING: Conscrypt native libraries not available. Falling back to JDK TLS. + FINE: Conscrypt native libraries not available. Falling back to JDK TLS. ``` - - Your application will continue running normally using classical TLS provided by the JDK. + - Your application will continue running normally using classical TLS provided by the JDK without emitting warnings in standard operational logs. ### 2.6 Verifying PQC in HTTP/JSON Client Libraries -You can verify that your Google Cloud HTTP/JSON Java client library is actively negotiating Post-Quantum Cryptography through operational logs or debug logging. Note that the log messages and logger categories below apply specifically to HTTP/JSON (REST) client libraries. - -#### 1. Check Operational Log Messages -When Conscrypt initializes successfully and configures PQC named groups, **no warning logs are emitted**. - -If your environment cannot load native Conscrypt libraries or cannot configure PQC groups, the library emits a concise, one-line warning at `Level.WARNING` and safely falls back to standard JDK TLS: -``` -WARNING: Conscrypt native libraries not available. Falling back to JDK TLS. -``` -If you **do not see this warning message** in your application logs, Conscrypt has successfully initialized and enabled PQC key exchange. +You can verify that your Google Cloud HTTP/JSON Java client library is actively negotiating Post-Quantum Cryptography through debug logging. Note that the log messages and logger categories below apply specifically to HTTP/JSON (REST) client libraries. -#### 2. Enable Debug Logging (`Level.FINE`) -To inspect the exact initialization status and any underlying native library loader exceptions, enable debug logging (`Level.FINE`) for `com.google.api.gax.httpjson.HttpJsonConscryptUtils`: +To inspect whether Conscrypt successfully initialized or why it fell back to JDK TLS, enable debug logging (`Level.FINE`) for `com.google.api.gax.httpjson.HttpJsonConscryptUtils`: - In `logging.properties`: ```properties com.google.api.gax.httpjson.HttpJsonConscryptUtils.level = FINE ``` -- If an error occurs during initialization, the full exception stacktrace (`UnsatisfiedLinkError`, `LinkageError`, etc.) will appear only at `FINE` level: +- When Conscrypt is unavailable or fails to initialize, it logs at `Level.FINE`: ``` + FINE: Conscrypt native library unavailable. Falling back to default JDK TLS. FINE: Conscrypt initialization failed with exception: java.lang.UnsatisfiedLinkError: ... ``` +- When Conscrypt initializes successfully, no fallback messages appear in the `FINE` logs. ### 2.7 Custom & Alternative Configurations