v158 · webtransport · keying material

Bind a key to a real session

The production flow in one page: connect to a WebTransport endpoint, export 32 bytes under a label your protocol owns, and use them as a session-bound secret. Both ends derive the same bytes from their own TLS stacks — no key ever crosses the wire. Everything below is a real call; whatever comes back — secret bytes or a connection error — is shown verbatim.

Chrome targets exportKeyingMaterial() for Chrome 158 behind the WebTransportExportKeyingMaterial runtime flag (--enable-blink-features=WebTransportExportKeyingMaterial, or chrome://flags/#enable-experimental-web-platform-features). This showcase has no HTTP/3 server, so the default endpoint is a public echo server; if it is unreachable from your network the attempt fails with the real error. A resolved export needs an established session — that is the spec, not a limitation of this page.

Connect and export

Any WebTransport server you can reach.

Convention: prefix with EXPORTER- and own the string.

Distinct contexts give distinct keys on the same session.

    Exported keying material (hex)

    — nothing exported yet —

    what you would do next

    The 32 bytes never leave the page. In a real protocol you would importKey them into WebCrypto and MAC a challenge — proving to the server that you hold a secret derived from this exact TLS session, which no token-stealing proxy can replay elsewhere. The derived-key pipeline concept runs that half for real.

    const transport = new WebTransport(url);
    await transport.ready;
    
    const enc = new TextEncoder();
    const ikm = await transport.exportKeyingMaterial(
      enc.encode("EXPORTER-showcase-binding v1"),
      enc.encode(serverNonce),      // the server names the exchange
      32,
    );
    // -> session-bound secret; the server derives the identical bytes
    //    from its TLS stack and verifies your MAC against them.

    see also