Flow 33 --- Composite Key Builder API Showcase
This scenario demonstrates 4 API approaches for creating composite keys, from verbose manual construction to simple one-liner factory methods. Shows the evolution of the API and helps developers choose the right construction method for their requirements.
Covers manual construction (full control), builder with manual algorithms (type-safe), builder with auto-selection (recommended), and factory one-liner (simplest). Also showcases client-side validation and advanced lifecycle configuration.
- Manual construction - Explicit setters for every parameter (8 lines)
- Builder with algorithms - Type-safe builder with explicit algorithm selection (6 lines)
- Builder auto-selection - Recommended approach with automatic algorithm selection (4 lines) ✅
- Factory one-liner - Simplest approach using pre-configured templates (1 line)
Key points
- Trade-offs: Control vs simplicity - manual gives full control, factory gives maximum simplicity
- Builder type-safety: All methods use enums (no string typos), IDE autocomplete, compile-time validation
- Auto-validation: Builder calls
.validate()automatically on.build(), preventing invalid configurations- Advanced config: Lifecycle management (usage limits, expiration, soft limits, key operations) available on all methods
When to use it
- Learning SDK API - Understand all construction approaches before choosing one
- Choosing API style - Evaluate control vs simplicity trade-offs for your use case
- Complex lifecycle configs - See advanced configuration with soft limits, expiration warnings
- Pre-configured templates - Discover factory methods for regulatory compliance (BSI, ANSSI, ETSI)
Shared helper – this code imports the utility class from example_util.md (configuration, authentication).
Complete Java implementation
src/main/java/co/ankatech/ankasecure/sdk/examples/ExampleScenario33.java
/** **************************************************************************
* FILE: ExampleScenario33.java
* SCENARIO: Composite Key Builder API Showcase
* TAGS: composite-keys, builder-pattern, fluent-api, validation
*************************************************************************** */
package co.ankatech.ankasecure.sdk.examples;
import co.ankatech.ankasecure.sdk.AnkaSecureSdk;
import co.ankatech.ankasecure.sdk.exception.InvalidInputException;
import co.ankatech.ankasecure.sdk.model.*;
import java.time.ZonedDateTime;
import java.util.Arrays;
import static co.ankatech.ankasecure.sdk.examples.ExampleUtil.*;
/**
* <h1>Scenario 33: Composite Key Builder API Showcase</h1>
* <p>
* Demonstrates all available methods for creating composite keys, from verbose
* manual configuration to simple one-liner factory methods. Shows the evolution
* of the API and best practices.
* </p>
*
* <h3>What You'll Learn:</h3>
* <ul>
* <li>4 different ways to create composite keys (from verbose to simple)</li>
* <li>How to use {@link CompositeKeyBuilder} fluent API</li>
* <li>How to use {@link RegulatoryTemplateFactory} one-liners</li>
* <li>Client-side validation with detailed error messages</li>
* <li>Advanced configuration options (usage limits, expiration, exportability)</li>
* </ul>
*
* <h3>API Evolution:</h3>
* <ol>
* <li><strong>Manual Construction:</strong> Full control, verbose (6-10 lines)</li>
* <li><strong>Builder with Manual Algorithms:</strong> Type-safe, explicit (5-7 lines)</li>
* <li><strong>Builder with Auto-Selection:</strong> Simpler, auto-selects algorithms (3-4 lines)</li>
* <li><strong>Factory One-Liner:</strong> Simplest, pre-configured (1 line)</li>
* </ol>
*
*
* @see CompositeKeyBuilder
* @see RegulatoryTemplateFactory
* @see GenerateCompositeKeySpec
*/
public class ExampleScenario33 {
public static void main(String[] args) {
try {
System.out.println("=================================================================");
System.out.println(" SCENARIO 33: Builder API Showcase");
System.out.println("=================================================================\n");
// Initialize SDK
java.util.Properties props = loadProperties();
AnkaSecureSdk sdk = authenticate(props);
// Method 1: Manual construction
demonstrateManualConstruction(sdk);
// Method 2: Builder with manual algorithms
demonstrateBuilderManual(sdk);
// Method 3: Builder with auto-selection
demonstrateBuilderAutoSelect(sdk);
// Method 4: Factory one-liner
demonstrateFactoryOneLiner(sdk);
// Advanced: Validation showcase
demonstrateValidation(sdk);
// Advanced: Full configuration
demonstrateAdvancedConfiguration(sdk);
System.out.println("\n=================================================================");
System.out.println(" ALL BUILDER PATTERNS DEMONSTRATED SUCCESSFULLY");
System.out.println("=================================================================");
} catch (Exception e) {
fatal("Scenario 33 failed", e);
}
}
/**
* Method 1: Manual construction (verbose, full control).
*/
private static void demonstrateManualConstruction(AnkaSecureSdk sdk) throws Exception {
System.out.println("[1/6] METHOD 1: Manual Construction (Verbose)");
System.out.println(" Lines of code: 8");
System.out.println(" Control level: Full\n");
GenerateCompositeKeySpec spec = new GenerateCompositeKeySpec()
.setKid("manual_" + System.currentTimeMillis())
.setMode(GenerateCompositeKeySpec.Mode.HYBRID_KEM_COMBINE)
.addComponent(ComponentSpec.classical(ClassicalCompositeAlgorithm.X25519))
.addComponent(ComponentSpec.pqc(PqcCompositeAlgorithm.ML_KEM_768))
.setKdf(Kdf.HKDF_SHA256)
.setMaxUsageLimit(1000000)
.setExportable(false);
// Manual validation (optional - builder does this automatically)
CompositeKeyValidator.validate(spec, new ServerAlgorithmResolver(sdk.getSupportedAlgorithms()));
System.out.println(" Code:");
System.out.println(" new GenerateCompositeKeySpec()");
System.out.println(" .setKid(...)");
System.out.println(" .setMode(Mode.HYBRID_KEM_COMBINE)");
System.out.println(" .addComponent(ComponentSpec.classical(...))");
System.out.println(" .addComponent(ComponentSpec.pqc(...))");
System.out.println(" .setKdf(Kdf.HKDF_SHA256)");
KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
System.out.println(" ✅ Manual key generated: " + result.getKid() + "\n");
}
/**
* Method 2: Builder with manual algorithm selection.
*/
private static void demonstrateBuilderManual(AnkaSecureSdk sdk) throws Exception {
System.out.println("[2/6] METHOD 2: Builder with Manual Algorithms");
System.out.println(" Lines of code: 6");
System.out.println(" Control level: High\n");
GenerateCompositeKeySpec spec = CompositeKeyBuilder
.forEncryption("builder_manual_" + System.currentTimeMillis())
.withAlgorithmCatalog(sdk.getSupportedAlgorithms())
.withClassical(ClassicalCompositeAlgorithm.RSA_3072)
.withPqc(PqcCompositeAlgorithm.ML_KEM_768)
.withKdf(Kdf.HKDF_SHA256)
.exportable(true)
.build(); // Auto-validates
System.out.println(" Code:");
System.out.println(" CompositeKeyBuilder.forEncryption(kid)");
System.out.println(" .withClassical(ClassicalCompositeAlgorithm.RSA_3072)");
System.out.println(" .withPqc(PqcCompositeAlgorithm.ML_KEM_768)");
System.out.println(" .withKdf(Kdf.HKDF_SHA256)");
System.out.println(" .build();");
KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
System.out.println(" ✅ Builder (manual) key generated: " + result.getKid() + "\n");
}
/**
* Method 3: Builder with auto-selection (recommended).
*/
private static void demonstrateBuilderAutoSelect(AnkaSecureSdk sdk) throws Exception {
System.out.println("[3/6] METHOD 3: Builder with Auto-Selection (RECOMMENDED)");
System.out.println(" Lines of code: 4");
System.out.println(" Control level: Medium (auto-selects algorithms)\n");
GenerateCompositeKeySpec spec = CompositeKeyBuilder
.forEncryption("builder_auto_" + System.currentTimeMillis())
.withAlgorithmCatalog(sdk.getSupportedAlgorithms())
.withSecurityLevel(NistSecurityLevel.LEVEL_3)
.withKdf(Kdf.HKDF_SHA256)
.build(); // Auto-selects X25519 + ML-KEM-768
System.out.println(" Code:");
System.out.println(" CompositeKeyBuilder.forEncryption(kid)");
System.out.println(" .withSecurityLevel(NistSecurityLevel.LEVEL_3)");
System.out.println(" .withKdf(Kdf.HKDF_SHA256)");
System.out.println(" .build();");
System.out.println("\n Auto-selected:");
System.out.println(" - Classical: X25519 (Level 3)");
System.out.println(" - PQC: ML-KEM-768 (Level 3)");
KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
System.out.println(" ✅ Builder (auto) key generated: " + result.getKid() + "\n");
}
/**
* Method 4: Factory one-liner (simplest).
*/
private static void demonstrateFactoryOneLiner(AnkaSecureSdk sdk) throws Exception {
System.out.println("[4/6] METHOD 4: Factory One-Liner (SIMPLEST)");
System.out.println(" Lines of code: 1");
System.out.println(" Control level: Low (pre-configured)\n");
// BSI compliance in one line
GenerateCompositeKeySpec spec = RegulatoryTemplateFactory.bsiHybrid(
"factory_bsi_" + System.currentTimeMillis(),
GenerateCompositeKeySpec.Mode.HYBRID_KEM_COMBINE
);
System.out.println(" Code:");
System.out.println(" RegulatoryTemplateFactory.bsiHybrid(kid, Mode.HYBRID_KEM_COMBINE);");
System.out.println("\n Pre-configured:");
System.out.println(" - Mode: HYBRID_KEM_COMBINE");
System.out.println(" - Classical: X25519 (Level 3)");
System.out.println(" - PQC: ML-KEM-768 (Level 3)");
System.out.println(" - KDF: HKDF-SHA256");
System.out.println(" - Compliance: BSI TR-02102-1 (Germany)");
KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
System.out.println(" ✅ Factory key generated: " + result.getKid() + "\n");
}
/**
* Demonstrates client-side validation with detailed error messages.
*/
private static void demonstrateValidation(AnkaSecureSdk sdk) {
System.out.println("[5/6] VALIDATION: Fail-Fast Error Detection");
System.out.println(" Demonstrating client-side validation\n");
// Test 1: Invalid component count
try {
System.out.println(" Test 1: Invalid component count...");
GenerateCompositeKeySpec invalid = new GenerateCompositeKeySpec()
.setKid("invalid_count")
.setMode(GenerateCompositeKeySpec.Mode.HYBRID_KEM_COMBINE)
.addComponent(ComponentSpec.classical(ClassicalCompositeAlgorithm.X25519))
// Missing PQC component
.setKdf(Kdf.HKDF_SHA256);
CompositeKeyValidator.validate(invalid, new ServerAlgorithmResolver(sdk.getSupportedAlgorithms()));
System.err.println(" ❌ Should have failed!");
} catch (InvalidInputException e) {
System.out.println(" ✅ Caught: " + e.getMessage());
}
// Test 2: KDF not applicable for DUALSIGN
try {
System.out.println("\n Test 2: KDF with DUALSIGN (invalid)...");
GenerateCompositeKeySpec invalid = CompositeKeyBuilder
.forSignature("invalid_kdf")
.withAlgorithmCatalog(sdk.getSupportedAlgorithms())
.withSecurityLevel(NistSecurityLevel.LEVEL_3)
.withKdf(Kdf.HKDF_SHA256) // Invalid for signatures
.build();
System.err.println(" ❌ Should have failed!");
} catch (InvalidInputException e) {
System.out.println(" ✅ Caught: " + e.getMessage());
}
// Test 3: Algorithm incompatibility
try {
System.out.println("\n Test 3: Algorithm mode incompatibility...");
GenerateCompositeKeySpec invalid = new GenerateCompositeKeySpec()
.setKid("invalid_mode")
.setMode(GenerateCompositeKeySpec.Mode.HYBRID_KEM_COMBINE)
.addComponent(ComponentSpec.classical(ClassicalCompositeAlgorithm.ED25519)) // Signature alg
.addComponent(ComponentSpec.pqc(PqcCompositeAlgorithm.ML_KEM_768)) // KEM alg
.setKdf(Kdf.HKDF_SHA256);
CompositeKeyValidator.validate(invalid, new ServerAlgorithmResolver(sdk.getSupportedAlgorithms()));
System.err.println(" ❌ Should have failed!");
} catch (InvalidInputException e) {
System.out.println(" ✅ Caught: " + e.getMessage());
}
System.out.println("\n All validation tests passed!\n");
}
/**
* Demonstrates advanced configuration with lifecycle management.
*/
private static void demonstrateAdvancedConfiguration(AnkaSecureSdk sdk) throws Exception {
System.out.println("[6/6] ADVANCED: Full Configuration with Lifecycle Management");
System.out.println(" Demonstrating all optional parameters\n");
GenerateCompositeKeySpec spec = CompositeKeyBuilder
.forEncryption("advanced_" + System.currentTimeMillis())
.withAlgorithmCatalog(sdk.getSupportedAlgorithms())
.withSecurityLevel(NistSecurityLevel.LEVEL_3)
.withKdf(Kdf.HKDF_SHA256)
.maxUsageLimit(1000000) // Hard limit
.softUsageLimit(800000) // Warning at 80%
.expiresAt(ZonedDateTime.parse("2030-12-31T23:59:59Z")) // Hard expiration
.softLimitExpiration(ZonedDateTime.parse("2030-06-30T23:59:59Z")) // Warning 6 months early
.exportable(true) // Allow public key export
.withKeyOps(Arrays.asList("encrypt", "decrypt")) // Explicit operations
.build();
System.out.println(" Configuration:");
System.out.println(" - Classical: X25519 (Level 3)");
System.out.println(" - PQC: ML-KEM-768 (Level 3)");
System.out.println(" - KDF: HKDF-SHA256");
System.out.println(" - Max Usage: 1,000,000 operations");
System.out.println(" - Soft Usage: 800,000 (80% warning)");
System.out.println(" - Hard Expiry: 2030-12-31");
System.out.println(" - Soft Expiry: 2030-06-30 (6 months warning)");
System.out.println(" - Exportable: Yes");
System.out.println(" - Operations: [encrypt, decrypt]");
KeyGenerationSummarySpec result = sdk.generateCompositeKey(spec);
System.out.println(" ✅ Advanced key generated: " + result.getKid());
System.out.println(" Status: " + result.getStatus());
System.out.println(" Max Usage: " + result.getMaxUsageLimit());
System.out.println(" Expires: " + result.getExpiresAt() + "\n");
}
}
Running the example
Expected output
=================================================================
SCENARIO 33: Builder API Showcase
=================================================================
[1/6] METHOD 1: Manual Construction (Verbose)
Lines of code: 8
Control level: Full
Code:
new GenerateCompositeKeySpec()
.setKid(...)
.setMode(Mode.HYBRID_KEM_COMBINE)
.addComponent(ComponentSpec.classical(...))
.addComponent(ComponentSpec.pqc(...))
.setKdf(Kdf.HKDF_SHA256)
✅ Manual key generated: manual_1735435200000
[2/6] METHOD 2: Builder with Manual Algorithms
Lines of code: 6
Control level: High
Code:
CompositeKeyBuilder.forEncryption(kid)
.withClassical(ClassicalCompositeAlgorithm.RSA_3072)
.withPqc(PqcCompositeAlgorithm.ML_KEM_768)
.withKdf(Kdf.HKDF_SHA256)
.build();
✅ Builder (manual) key generated: builder_manual_1735435200100
[3/6] METHOD 3: Builder with Auto-Selection (RECOMMENDED)
Lines of code: 4
Control level: Medium (auto-selects algorithms)
Code:
CompositeKeyBuilder.forEncryption(kid)
.withSecurityLevel(NistSecurityLevel.LEVEL_3)
.withKdf(Kdf.HKDF_SHA256)
.build();
Auto-selected:
- Classical: X25519 (Level 3)
- PQC: ML-KEM-768 (Level 3)
✅ Builder (auto) key generated: builder_auto_1735435200200
[4/6] METHOD 4: Factory One-Liner (SIMPLEST)
Lines of code: 1
Control level: Low (pre-configured)
Code:
RegulatoryTemplateFactory.bsiHybrid(kid, Mode.HYBRID_KEM_COMBINE);
Pre-configured:
- Mode: HYBRID_KEM_COMBINE
- Classical: X25519 (Level 3)
- PQC: ML-KEM-768 (Level 3)
- KDF: HKDF-SHA256
- Compliance: BSI TR-02102-1 (Germany)
✅ Factory key generated: factory_bsi_1735435200300
[5/6] VALIDATION: Fail-Fast Error Detection
Demonstrating client-side validation
Test 1: Invalid component count...
✅ Caught: [Error message about missing component]
Test 2: KDF with DUALSIGN (invalid)...
✅ Caught: [Error message about KDF not applicable for signatures]
Test 3: Algorithm mode incompatibility...
✅ Caught: [Error message about Ed25519 being signature algorithm]
All validation tests passed!
[6/6] ADVANCED: Full Configuration with Lifecycle Management
Demonstrating all optional parameters
Configuration:
- Classical: X25519 (Level 3)
- PQC: ML-KEM-768 (Level 3)
- KDF: HKDF-SHA256
- Max Usage: 1,000,000 operations
- Soft Usage: 800,000 (80% warning)
- Hard Expiry: 2030-12-31
- Soft Expiry: 2030-06-30 (6 months warning)
- Exportable: Yes
- Operations: [encrypt, decrypt]
✅ Advanced key generated: advanced_1735435200400
Status: ACTIVE
Max Usage: 1000000
Expires: 2030-12-31T23:59:59Z
=================================================================
ALL BUILDER PATTERNS DEMONSTRATED SUCCESSFULLY
=================================================================
Where next?
© 2025 ANKATech Solutions INC. All rights reserved.