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-256symmetric 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
/*
* Copyright 2025 ANKATech Solutions Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package co.ankatech.ankasecure.sdk.examples;
import co.ankatech.ankasecure.sdk.AuthenticatedSdk;
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.*;
/**
* Scenario 7 — AES-256 Compact JWE Helpers.
*
* <p>This scenario showcases the SDK's <strong>non-streaming</strong> helpers
* for symmetric Compact JWE operations:</p>
* <ol>
* <li>Generate an <code>AES-256</code> key (<code>kty="oct"</code>).</li>
* <li>Encrypt a plaintext file (helper stores a Compact JWE).</li>
* <li>Decrypt the ciphertext (helper resolves the key from the JWE header).</li>
* <li>Print metadata and validate integrity.</li>
* </ol>
*
* <p><b>Implementation notes (Java 21+):</b></p>
* <ul>
* <li>All filesystem interactions use the {@link java.nio.file.Path} API.</li>
* <li>UTF-8 is enforced explicitly for deterministic encoding.</li>
* <li>Temporary artefacts reside under <kbd>temp_files/</kbd>.</li>
* </ul>
*
* <p><b>Thread-safety:</b> this class is stateless and immutable.</p>
*
* @author ANKATech Solutions Inc.
* @since 3.0.0
* @see ExampleUtil
* @see AuthenticatedSdk
*/
public final class ExampleScenario7 {
/** No instantiation — this class only exposes {@link #main(String[])}. */
private ExampleScenario7() { }
/**
* Runs the AES-256 compact JWE encrypt/decrypt scenario.
*
* <p>Loads CLI properties, authenticates against ANKASecure©,
* and delegates to the scenario logic. On any unrecoverable error
* the JVM terminates via
* {@link ExampleUtil#fatal(String, Throwable)}.</p>
*
* @param args command-line arguments (ignored)
*/
public static void main(final String[] args) {
System.out.println("===== SCENARIO 7 START =====");
System.out.println("""
Purpose :
* AES-256 Compact-JWE encrypt / decrypt helpers
* Non-streaming - full token handled in memory
Steps :
1) Generate AES-256 key
2) Create sample payload
3) Encrypt payload (compact JWE)
4) Decrypt ciphertext
5) Validate integrity
--------------------------------------------------------------""");
try {
ensureTempDir(TEMP_DIR);
Properties props = loadProperties();
AuthenticatedSdk sdk = authenticate(props);
runScenario(sdk);
} catch (Exception ex) {
fatal("Scenario 7 failed", ex);
}
System.out.println("===== SCENARIO 7 END =====");
}
/**
* Executes the 4-step AES-256 compact JWE scenario.
*
* <ol>
* <li>Create sample plaintext file.</li>
* <li>Generate AES-256 symmetric key.</li>
* <li>Encrypt file (compact JWE).</li>
* <li>Decrypt and validate integrity.</li>
* </ol>
*
* @param sdk an authenticated {@link AuthenticatedSdk} instance;
* must not be {@code null}
* @throws Exception if any step fails
*/
private static void runScenario(final AuthenticatedSdk 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-GCM-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 -- validation --------------------------------------------------- */
boolean match = FileIO.readUtf8(plain)
.equals(FileIO.readUtf8(recovered));
System.out.println(match
? "[5] SUCCESS - plaintext matches."
: "[5] FAILURE - plaintext mismatch.");
}
}
How to run
Console milestones:
-
AES-256 key generation
-
Compact-JWE encryption →
scenario7.jwe -
Decryption →
scenario7_dec.txt -
SUCCESS message confirming byte-perfect round-trip