Flow 22 --- Detached-JWS Stream Verification
This scenario walks through a constant-memory verification of a detached JWS created from a multi-megabyte payload:
-
Generate an XMSS key-pair that can sign and verify.
-
Create a 100 KB dummy payload.
-
Sign that file as a detached JWS (General JSON with
"payload": null
) viasignFileStream
. -
Verify the detached signature in streaming mode with
verifySignatureStream
. -
Print rich server metadata and confirm the signature's validity.
Key points
Uses tree-based XMSS signatures --- quantum-resistant and state-aware.
Detached-JWS keeps large payloads out of the token; the signature file stays tiny.
Streaming helpers (
signFileStream
,verifySignatureStream
) hold only a small buffer in RAM --- ideal for 100 MiB+ artefacts.Produces repeatable 100 KB test data under
temp_files/
, then cleans itself up automatically.
When to use it
-
High-volume log pipelines that need to stamp gigabytes with a quantum-safe signature without exhausting memory.
-
Content-distribution networks where the asset (video, image, dataset) travels separately from its JWS header & signature.
-
Compliance or audit trails that demand verifiable integrity proofs while keeping tokens lightweight.
Shared helper – this code imports the utility class from
example_util.md (configuration, authentication, JSON).
Complete Java implementation
src/main/java/co/ankatech/ankasecure/sdk/examples/ExampleScenario22.java
/* *****************************************************************************
* FILE: ExampleScenario22.java
* Copyright © 2025 Anka Technologies.
* SPDX-License-Identifier: MIT
* ---------------------------------------------------------------------------
* Scenario 22 – Streaming Verification of a *Detached JWS*
* ---------------------------------------------------------------------------
* Demonstrates how to:
* * Generate an **XMSS** key-pair capable of sign / verify.
* * Produce a 100 Kb payload and sign it as a *detached JWS*
* (General JSON; `"payload": null`) using `signFileStream`.
* * Verify that signature in constant-memory streaming mode via
* `verifySignatureStream`.
*
* All artefacts live only under <temp_files/> and are recreated on every run;
* no manual clean-up is needed.
* ****************************************************************************/
package co.ankatech.ankasecure.sdk.examples;
import co.ankatech.ankasecure.sdk.AnkaSecureSdk;
import co.ankatech.ankasecure.sdk.model.GenerateKeySpec;
import co.ankatech.ankasecure.sdk.model.SignResult;
import co.ankatech.ankasecure.sdk.model.VerifySignatureResult;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;
/**
* End-to-end, file-oriented demonstration of streaming *detached JWS*
* verification with an XMSS key.
*/
public final class ExampleScenario22 {
private static final String SIGN_KID =
"scenario22_XMSS_" + System.currentTimeMillis();
private static final Path TMP_DIR = Path.of("temp_files");
private static final Path LARGE_PAYLOAD = TMP_DIR.resolve("scenario22_payload.bin");
private static final Path DETACHED_SIG = TMP_DIR.resolve("scenario22_payload.sig");
public static void main(String[] args) {
System.out.println("===== SCENARIO 22 START =====");
try {
Files.createDirectories(TMP_DIR);
Properties props = ExampleUtil.loadProperties();
AnkaSecureSdk sdk = ExampleUtil.authenticate(props);
runScenario(sdk);
} catch (Exception ex) {
fatal("Scenario 22 failed", ex);
}
System.out.println("===== SCENARIO 22 END =====");
}
private static void runScenario(AnkaSecureSdk sdk) throws Exception {
/* 1 – XMSS key generation ------------------------------------- */
sdk.generateKey(new GenerateKeySpec()
.setKid(SIGN_KID)
.setKty("XMSS")
.setAlg("XMSS")
.setKeyOps(List.of("sign", "verify")));
System.out.println("[1] XMSS key generated -> kid = " + SIGN_KID);
/* 2 – 100 Kb dummy payload ------------------------------------ */
byte[] blob = new byte[3 * 1024 * 1024]; // zero-filled buffer
Files.write(LARGE_PAYLOAD, blob);
System.out.println("[2] Payload created -> " + LARGE_PAYLOAD);
/* 3 – detached-JWS streaming sign ----------------------------- */
SignResult signMeta = sdk.signFileStream(SIGN_KID, LARGE_PAYLOAD, DETACHED_SIG);
System.out.println("[3] Detached JWS written -> " + DETACHED_SIG);
printSignMeta(signMeta);
/* 4 – detached-JWS streaming verify --------------------------- */
VerifySignatureResult verifyMeta =
sdk.verifySignatureStream(LARGE_PAYLOAD, DETACHED_SIG);
System.out.println("[4] Signature valid? -> " + verifyMeta.isValid());
printVerifyMeta(verifyMeta);
}
/* ------------------------- diagnostics -------------------------- */
private static void printSignMeta(SignResult r) {
System.out.println("----- SIGN METADATA -----");
System.out.println("Key requested : " + ns(r.getKeyRequested()));
System.out.println("Key used : " + ns(r.getActualKeyUsed()));
System.out.println("Algorithm : " + ns(r.getAlgorithmUsed()));
printWarnings(r.getWarnings());
}
private static void printVerifyMeta(VerifySignatureResult r) {
System.out.println("----- VERIFY METADATA -----");
System.out.println("Key requested : " + ns(r.getKeyRequested()));
System.out.println("Key used : " + ns(r.getActualKeyUsed()));
System.out.println("Algorithm : " + ns(r.getAlgorithmUsed()));
printWarnings(r.getWarnings());
}
private static void printWarnings(List<String> w) {
if (w != null && !w.isEmpty()) {
System.out.println("Warnings :");
w.forEach(x -> System.out.println(" * " + x));
}
}
private static String ns(String s) {
return (s == null || s.isBlank()) ? "(none)" : s;
}
private static void fatal(String msg, Throwable t) {
System.err.println(MessageFormat.format("{0}: {1}",
msg, t != null ? t.getMessage() : "(no cause)"));
if (t != null) t.printStackTrace(System.err);
System.exit(1);
}
private ExampleScenario22() {/* no-instantiation */}
}
How to run
Console milestones
-
XMSS key generated
-
100 KB payload written to
scenario22_payload.bin
-
Detached-JWS signature file created
-
Signature verified valid in streaming mode
-
Sign & verify metadata (key IDs, algorithm, warnings)
Where next?
© 2025 Anka Technologies. All rights reserved.