Skip to content

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.

  1. Manual construction - Explicit setters for every parameter (8 lines)
  2. Builder with algorithms - Type-safe builder with explicit algorithm selection (6 lines)
  3. Builder auto-selection - Recommended approach with automatic algorithm selection (4 lines) ✅
  4. 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

package co.ankatech.ankasecure.sdk.examples;

import co.ankatech.ankasecure.sdk.AuthenticatedSdk;
import co.ankatech.ankasecure.sdk.model.*;
import co.ankatech.secure.client.model.KeyRequest;

import java.util.List;

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

/**
 * Scenario 33 — Algorithm Discovery and Selection Patterns.
 *
 * <p>Demonstrates advanced techniques for discovering, filtering, and selecting
 * algorithms from the server's algorithm catalog. Shows how to build flexible
 * key generation logic that adapts to server capabilities.</p>
 *
 * <h3>What You'll Learn:</h3>
 * <ul>
 *   <li>How to query the algorithm catalog with complex filters</li>
 *   <li>How to select algorithms programmatically based on requirements</li>
 *   <li>How to handle multiple valid options</li>
 *   <li>How to construct KeyRequest from discovered algorithms</li>
 * </ul>
 *
 * <h3>Discovery Patterns:</h3>
 * <ol>
 *   <li>Find all HYBRID algorithms</li>
 *   <li>Filter by security level and status</li>
 *   <li>Filter by key operations (encrypt, sign, etc.)</li>
 *   <li>Select based on compliance standards</li>
 * </ol>
 *
 * @author ANKATech Solutions Inc.
 * @since 3.0.0
 */
public final class ExampleScenario33 {

    private ExampleScenario33() { }

    public static void main(String[] args) {
        try {
            System.out.println("=================================================================");
            System.out.println("  SCENARIO 33: Algorithm Discovery and Selection");
            System.out.println("=================================================================\n");

            java.util.Properties props = loadProperties();
            AuthenticatedSdk sdk = authenticate(props);

            discoverAllHybridAlgorithms(sdk);
            discoverBySecurityLevel(sdk);
            discoverByComplianceStandard(sdk);
            discoverCompositeSignatures(sdk);

            System.out.println("\n=================================================================");
            System.out.println("  ALGORITHM DISCOVERY PATTERNS DEMONSTRATED");
            System.out.println("=================================================================");

        } catch (Exception e) {
            fatal("Scenario 33 failed", e);
        }
    }

    /**
     * Pattern 1: Discover all hybrid algorithms.
     */
    private static void discoverAllHybridAlgorithms(AuthenticatedSdk sdk) throws Exception {
        System.out.println("[1/4] DISCOVER ALL HYBRID ALGORITHMS");
        System.out.println();

        AlgorithmFilter filter = AlgorithmFilter.builder()
            .withCategory(AlgorithmInfo.Category.HYBRID)
            .withStatus(AlgorithmInfo.Status.RECOMMENDED)
            .build();

        List<AlgorithmInfo> hybrids = sdk.getSupportedAlgorithms(filter);

        System.out.println("      Found " + hybrids.size() + " hybrid algorithms:");
        hybrids.forEach(alg -> {
            System.out.println("      - " + alg.getKty() + ": " + alg.getAlg() +
                             " (Level " + alg.getSecurityLevel() + ")");
        });
        System.out.println();
    }

    /**
     * Pattern 2: Filter by security level.
     */
    private static void discoverBySecurityLevel(AuthenticatedSdk sdk) throws Exception {
        System.out.println("[2/4] DISCOVER BY SECURITY LEVEL");
        System.out.println();

        // Find Level 3 hybrid KEM algorithms
        AlgorithmFilter filter = AlgorithmFilter.builder()
            .withCategory(AlgorithmInfo.Category.HYBRID)
            .withMinSecurityLevel(3)
            .withMaxSecurityLevel(3)
            .withKeyOps("encrypt", "decrypt")
            .withStatus(AlgorithmInfo.Status.RECOMMENDED)
            .build();

        List<AlgorithmInfo> level3Hybrids = sdk.getSupportedAlgorithms(filter);

        if (!level3Hybrids.isEmpty()) {
            AlgorithmInfo selected = level3Hybrids.get(0);

            System.out.println("      Selected algorithm: " + selected.getAlg());
            System.out.println("      Security level: " + selected.getSecurityLevel());
            System.out.println("      Key operations: " + selected.getKeyOps());

            // Create key with discovered algorithm
            KeyRequest request = new KeyRequest()
                .kid("auto_selected_level3_" + System.currentTimeMillis())
                .kty(selected.getKty())
                .alg(selected.getAlg())
                .kdf("HKDF-SHA256");

            KeyMetadata metadata = sdk.generateKey(request);
            System.out.println("\n      ✅ Key created: " + metadata.getKid());
            System.out.println("      Algorithm: " + metadata.getAlg());
        }
        System.out.println();
    }

    /**
     * Pattern 3: Filter by compliance standards.
     */
    private static void discoverByComplianceStandard(AuthenticatedSdk sdk) throws Exception {
        System.out.println("[3/4] DISCOVER BY COMPLIANCE STANDARD");
        System.out.println();

        // Find NIST-standardized hybrid algorithms
        AlgorithmFilter filter = AlgorithmFilter.builder()
            .withCategory(AlgorithmInfo.Category.HYBRID)
            .withStandards("NIST")
            .withStatus(AlgorithmInfo.Status.RECOMMENDED)
            .build();

        List<AlgorithmInfo> nistHybrids = sdk.getSupportedAlgorithms(filter);

        System.out.println("      NIST-standardized hybrids: " + nistHybrids.size());
        nistHybrids.forEach(alg -> {
            System.out.println("      - " + alg.getAlg() + " (Standards: " + alg.getStandards() + ")");
        });
        System.out.println();
    }

    /**
     * Pattern 4: Discover composite signature algorithms.
     */
    private static void discoverCompositeSignatures(AuthenticatedSdk sdk) throws Exception {
        System.out.println("[4/4] DISCOVER COMPOSITE SIGNATURE ALGORITHMS");
        System.out.println();

        AlgorithmFilter filter = AlgorithmFilter.builder()
            .withCategory(AlgorithmInfo.Category.HYBRID)
            .withKeyOps("sign", "verify")
            .withStatus(AlgorithmInfo.Status.RECOMMENDED)
            .build();

        List<AlgorithmInfo> signatureHybrids = sdk.getSupportedAlgorithms(filter);

        if (!signatureHybrids.isEmpty()) {
            AlgorithmInfo selected = signatureHybrids.get(0);

            System.out.println("      Selected: " + selected.getAlg());
            System.out.println("      Key type: " + selected.getKty());
            System.out.println("      Operations: " + selected.getKeyOps());

            // Create composite signature key
            KeyRequest request = new KeyRequest()
                .kid("auto_dual_sig_" + System.currentTimeMillis())
                .kty(selected.getKty())
                .alg(selected.getAlg())
                .verificationPolicy(KeyRequest.VerificationPolicyEnum.ALL);

            KeyMetadata metadata = sdk.generateKey(request);
            System.out.println("\n      ✅ Created: " + metadata.getKid());
            System.out.println("      Algorithm: " + metadata.getAlg());
            System.out.println("      Type: " + metadata.getKty());
        }
        System.out.println();
    }
}

Running the example

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

Where next?

© 2025 ANKATech Solutions INC. All rights reserved.