Skip to content

Flow 7 -- AES-256 Compact-JWE Encrypt / Decrypt (Non-Streaming)

This scenario walks through a symmetric, non-streaming round-trip with an AES-256 key:

  • Generate an AES-256 symmetric key (kty="oct").

  • Encrypt a plaintext file → compact JWE (five B64URL segments).

  • Decrypt the compact JWE back to plaintext.

  • Validate that the recovered bytes equal the original.

Key points

  • Uses encryptFile( ) / decryptFile( ) helpers (entire token in memory).
  • Demonstrates the Compact JWE format that's easy to persist or embed.
  • Shows server-side metadata (key actually used, algorithm, warnings).

When to use it

  • Small-to-mid-sized artefacts – ideal for files up to a 5 MB where a single, self-contained token is simpler than a multipart stream.
  • High-throughput workloads – AES-256 is symmetric, fast and FIPS-validated, making it perfect for CI pipelines, database dumps or nightly backups that must finish quickly.
  • Easy embedding & transport – the compact-JWE string can be logged, emailed, dropped into JSON manifests or pasted into bug reports without worrying about binary encoding or multipart boundaries.

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/ExampleScenario7.java

/* *****************************************************************************
 * FILE: ExampleScenario7.java
 * Copyright © 2025 Anka Technologies.
 * ---------------------------------------------------------------------------
 * Scenario 7 – AES-256 Bulk Encrypt / Decrypt (Compact JWE helpers)
 * ---------------------------------------------------------------------------
 *  1. Generate an AES-256 symmetric key (kty = "oct", alg = "AES-256").
 *  2. Encrypt a local file with encryptFile → Compact JWE (five B64URL segments).
 *  3. Decrypt that JWE with decryptFile (kid resolved from header).
 *  4. Display rich server metadata.
 *  5. Confirm the recovered plaintext matches the original.
 * ---------------------------------------------------------------------------
 * All transient artefacts are created inside the <temp_files/> directory.
 * ****************************************************************************/
package co.ankatech.ankasecure.sdk.examples;

import co.ankatech.ankasecure.sdk.AnkaSecureSdk;
import co.ankatech.ankasecure.sdk.model.DecryptResultMetadata;
import co.ankatech.ankasecure.sdk.model.EncryptResult;
import co.ankatech.ankasecure.sdk.model.GenerateKeySpec;
import co.ankatech.ankasecure.sdk.util.FileIO;

import java.nio.file.Path;
import java.util.Properties;

import static co.ankatech.ankasecure.sdk.examples.ExampleUtil.*;

/**
 * <h2>Scenario&nbsp;7 – AES-256 Compact&nbsp;JWE Helpers</h2>
 *
 * <p>This scenario demonstrates the SDK’s <strong>non-streaming</strong>
 * helpers for symmetric Compact&nbsp;JWE operations:</p>
 * <ol>
 *   <li>Generate an AES-256 key.</li>
 *   <li>Encrypt a plaintext file (helper stores a Compact&nbsp;JWE).</li>
 *   <li>Decrypt the ciphertext (helper resolves the correct key from the JWE header).</li>
 *   <li>Print metadata and validate integrity.</li>
 * </ol>
 *
 * <p><b>Implementation notes (Java&nbsp;21+):</b></p>
 * <ul>
 *   <li>All filesystem interactions use the {@link java.nio.file.Path} API.</li>
 *   <li>UTF-8 is explicitly specified for deterministic encoding.</li>
 *   <li>Directory creation delegates to {@link ExampleUtil#ensureTempDir(Path)}.</li>
 * </ul>
 *
 * <p><b>Thread-safety:</b> this class is stateless and immutable.</p>
 *
 * @author ANKATech – Security Engineering
 * @since 2.1.0
 */
public final class ExampleScenario7 {

    /* ====================================================================== */
    /**
     * Entry-point.
     *
     * @param args ignored
     */
    public static void main(final String[] args) {

        System.out.println("===== SCENARIO 7 START =====");
        System.out.println("""
                Purpose :
                  * AES-256 non-streaming Compact-JWE encryption helpers
                  * Demonstrates encryptFile & decryptFile APIs
                --------------------------------------------------------------""");

        try {
            ensureTempDir(TEMP_DIR);

            Properties props = loadProperties();
            AnkaSecureSdk sdk = authenticate(props);

            runScenario(sdk);

        } catch (Exception ex) {
            fatal("Scenario 7 failed", ex);
        }

        System.out.println("===== SCENARIO 7 END =====");
    }

    /* ====================================================================== */
    /**
     * Executes all steps of Scenario&nbsp;7.
     *
     * @param sdk an authenticated {@link AnkaSecureSdk} instance
     *
     * @throws Exception if any step fails
     */
    private static void runScenario(final AnkaSecureSdk sdk) throws Exception {

        /* 1 ── create sample plaintext ---------------------------------- */
        Path plain = TEMP_DIR.resolve("scenario7_plain.txt");
        FileIO.writeUtf8(
                plain,
                "Scenario-7 – AES-256 Compact-JWE encrypt / decrypt demo.");
        System.out.println("[1] Plaintext ready       -> " + plain.toAbsolutePath());

        /* 2 ── generate AES-256 key ------------------------------------- */
        String kid = "sc7_aes256_" + System.currentTimeMillis();
        sdk.generateKey(new GenerateKeySpec()
                .setKid(kid)
                .setKty("oct")
                .setAlg("AES-256"));
        System.out.println("[2] Key generated         -> kid = " + kid);

        /* 3 ── encrypt file (Compact JWE) ------------------------------- */
        Path jweFile = TEMP_DIR.resolve("scenario7.jwe");
        EncryptResult encMeta = sdk.encryptFile(kid, plain, jweFile);
        System.out.println("[3] Ciphertext stored      -> " + jweFile.toAbsolutePath());
        printEncryptMeta(encMeta);

        /* 4 ── decrypt --------------------------------------------------- */
        Path recovered = TEMP_DIR.resolve("scenario7_dec.txt");
        DecryptResultMetadata decMeta = sdk.decryptFile(jweFile, recovered);
        System.out.println("[4] Decrypted file         -> " + recovered.toAbsolutePath());
        printDecryptMeta(decMeta);

        /* 5 ── round-trip check ---------------------------------------- */
        boolean match = FileIO.readUtf8(plain)
                .equals(FileIO.readUtf8(recovered));
        System.out.println(match
                ? "[5] SUCCESS – plaintext matches."
                : "[5] FAILURE – plaintext mismatch.");
    }

    /**
     * Private constructor prevents instantiation.
     */
    private ExampleScenario7() {
        /* utility class – no instantiation */
    }
}

How to run


mvn -q compile exec:java\
  -Dexec.mainClass="co.ankatech.ankasecure.sdk.examples.ExampleScenario7"

Console milestones:

  • AES-256 key generation

  • Compact-JWE encryption → scenario7.jwe

  • Decryption → scenario7_dec.txt

  • SUCCESS message confirming byte-perfect round-trip


Where next?