Skip to content

Composite Hybrid Keys — Best Practices

Practical guidance for implementing quantum-resistant composite cryptography in production.


Algorithm Selection

For encryption (HYBRID_KEM_COMBINE): - X25519 + ML-KEM-768 (RECOMMENDED) - Security: NIST Level 3 (192-bit equivalent) - Performance: ~5ms encryption - Use case: 95% of production scenarios

For signatures (DUALSIGN): - Ed25519 + ML-DSA-65 (RECOMMENDED) - Security: NIST Level 3 (192-bit equivalent) - Signature size: ~3.3KB - Use case: Document signing, API authentication

Security Level Matching

Critical: Classical and PQC components must match security levels.

NIST Level Classical PQC KEM PQC Signature
1 (128-bit) X25519 ML-KEM-512 ML-DSA-44
3 (192-bit) X25519 ML-KEM-768 ML-DSA-65
5 (256-bit) RSA-4096 ML-KEM-1024 ML-DSA-87

Don't mix: X25519 (Level 3) + ML-KEM-512 (Level 1) = security level mismatch error


Verification Policy Selection (DUALSIGN)

Behavior: Both classical AND PQC signatures must be valid.

Use when: - Maximum security required - Legal contracts or compliance documents - Government or classified data

{
  "verificationPolicy": "ALL"
}

ANY (Migration Scenarios)

Behavior: At least one signature must be valid.

Use when: - Gradual migration from classical to PQC - Testing compatibility with external systems - Fallback scenarios

⚠️ Warning: Less secure than ALL — use temporarily during migration only.

CLASSICAL_REQUIRED / PQC_REQUIRED

Use when: - Legacy system compatibility (CLASSICAL_REQUIRED) - Future-proofing only (PQC_REQUIRED)


Key Lifecycle Management

Rotation Strategy

Recommendation: Rotate composite keys every 12 months for high-security scenarios.

# 1. Generate new composite key
curl -X POST /api/key-management/composite-keys \
  -d '{"kid": "composite-2026", "mode": "HYBRID_KEM_COMBINE", ...}'

# 2. Re-encrypt data with new key (no plaintext exposure)
curl -X POST /api/crypto/re-encrypt \
  -d '{"sourceKid": "composite-2025", "targetKid": "composite-2026", ...}'

# 3. Retire old key
curl -X PATCH /api/key-management/keys/composite-2025 \
  -d '{"status": "retired"}'

Expiration Settings

Data Sensitivity Recommended Lifetime Example
Top Secret 6-12 months Government classified
Confidential 12-24 months Financial records
Internal 24-36 months Business documents

Usage Limits

Set maxUsageLimit to prevent key overuse:

GenerateCompositeKeySpec spec = new GenerateCompositeKeySpec()
    .setMaxUsageLimit(1000000) // 1M operations
    .setExpiresAt(LocalDateTime.now().plusYears(2));

Recommendation: 1M operations or 2 years (whichever comes first).


Performance Optimization

When to Use Composite vs Simple Keys

Scenario Recommendation Reason
Long-term archives (10+ years) Composite HNDR protection
High-frequency API (>1000 ops/sec) Simple Performance critical
Development/testing Simple Faster iteration
Production sensitive data Composite Defense-in-depth

Streaming for Large Files

For files >5MB, use streaming APIs:

// Streaming avoids loading entire file into memory
EncryptResult result = sdk.encryptFileStream(
    "composite-key-id",
    Path.of("large-file.dat"),
    Path.of("large-file.enc")
);

Benefit: Constant ~2MB memory usage regardless of file size.


Error Handling

Common Errors

"Security level mismatch":

{
  "error": "SECURITY_LEVEL_MISMATCH",
  "message": "Classical component (Level 3) and PQC component (Level 1) must match"
}

Solution: Use matching security levels (X25519 + ML-KEM-768 for Level 3).

"Verification policy not satisfied":

{
  "error": "VERIFICATION_POLICY_NOT_MET",
  "message": "Policy ALL requires both signatures valid, but classical signature failed"
}

Solution: Check both component private keys are available and valid.

Retry Strategy

Transient errors (500, 503): Retry with exponential backoff.

int maxRetries = 3;
int delayMs = 1000;

for (int i = 0; i < maxRetries; i++) {
    try {
        return sdk.generateCompositeKey(spec);
    } catch (ServiceUnavailableException ex) {
        Thread.sleep(delayMs * (1 << i)); // 1s, 2s, 4s
    }
}

Permanent errors (400, 422): Fix request and retry.


Security Checklist

Before deploying composite keys to production:

  • [ ] Security levels matched (classical and PQC at same NIST level)
  • [ ] Verification policy set to ALL for production signatures
  • [ ] Key rotation schedule defined (12-24 months)
  • [ ] Usage limits configured (max operations and expiration)
  • [ ] Monitoring and alerting enabled (key health, expiration warnings)
  • [ ] Backup and disaster recovery tested
  • [ ] API credentials securely stored (not hardcoded)
  • [ ] Client-side format detection implemented (Content-Type header)

Regulatory Compliance

Compliance Templates

ANKASecure provides pre-configured policy templates for regulatory compliance:

Template Regulation When to Use
BSI_HYBRID_ENFORCED German BSI TR-02102-1 German government/critical infrastructure
ANSSI_HYBRID_ENFORCED French ANSSI RGS v2 French defense/government
ETSI_HYBRID_ENFORCED ETSI TS 103 744 EU telecommunications (5G/6G)
EU_UNIFIED_HYBRID BSI + ANSSI + ETSI Multi-national EU operations
NIST_HYBRID_OPTIONAL NIST SP 800-227 US federal agencies

Contact your ANKASecure administrator to configure the appropriate template for your organization.

Compliance Checklist

Before deploying to production:

For EU Customers (BSI/ANSSI/ETSI):

  • [ ] Policy template configured (BSI_HYBRID_ENFORCED, ANSSI_HYBRID_ENFORCED, or ETSI_HYBRID_ENFORCED)
  • [ ] Only composite keys used for PQC operations
  • [ ] All keys use Security Level 3 or higher (ML-KEM-768+, ML-DSA-65+)
  • [ ] Hash-based signatures (SLH-DSA) can be standalone if needed
  • [ ] KDF selection aligned with template (check allowedKdfs)

For US Customers (NIST):

  • [ ] Policy template configured (NIST_HYBRID_OPTIONAL or DEFAULT)
  • [ ] HKDF-SHA256 used for composite keys
  • [ ] FIPS 203/204/205 algorithms used (ML-KEM, ML-DSA, SLH-DSA)

Understanding Key Derivation Functions (KDF)

When creating hybrid encryption keys (HYBRID_KEM_COMBINE mode), ANKASecure must combine the shared secrets from both the classical and PQC components into a single final key. This is where Key Derivation Functions (KDFs) come into play.

Why KDFs matter:

  • Security: Proper combination prevents weaknesses in individual secrets from compromising the final key
  • Standards compliance: Different regulations mandate specific KDF algorithms
  • Interoperability: Using standardized KDFs ensures compatibility with regulatory frameworks

Available KDFs in ANKASecure:

1. HKDF-SHA256 (Default - NIST Approved)

What it does:

  • Extracts entropy from both secrets using a salt
  • Expands the extracted key material to desired length
  • Two-phase process: Extract-then-Expand

When to use:

  • ✅ US federal agencies or NIST compliance required
  • ✅ Conservative, well-studied cryptographic choice
  • ✅ Default recommendation for most users
  • ✅ Universally accepted (works with all templates)

Regulatory: - Required by: NIST SP 800-56C Rev. 2, NIST SP 800-227 - Accepted by: BSI, ANSSI, ETSI (as fallback)

2. CatKDF (ETSI Standard)

What it does:

  • Directly concatenates both secrets
  • Applies KDF with context information
  • Single-phase process: Concatenate-then-derive

When to use:

  • ✅ EU telecommunications sector (5G/6G)
  • ✅ ETSI TS 103 744 compliance required
  • ✅ Simpler construction, slightly better performance

Regulatory: - Required by: ETSI TS 103 744 (EU Telecom) - Accepted by: BSI

3. CasKDF (ETSI Cascade - High Security)

What it does:

  • Sequential injection of secrets with chaining states
  • Cascaded construction with intermediate derivations
  • Most complex but strongest guarantees

When to use:

  • ✅ High-security EU telecommunications
  • ✅ Defense or critical infrastructure
  • ✅ Maximum security posture required

Regulatory: - Required by: ETSI TS 103 744 (high-security variant) - Accepted by: BSI

KDF Selection Decision Tree

graph TD Start{What is your primary<br/>regulatory requirement?} Start -->|USA Federal/NIST| NIST_KDF[HKDF-SHA256<br/>✅ Required by NIST] Start -->|Germany/BSI| BSI_Choice{Security<br/>posture?} Start -->|France/ANSSI| ANSSI_KDF[HKDF-SHA256<br/>✅ Required by ANSSI] Start -->|EU Telecom/ETSI| ETSI_Choice{5G/6G or<br/>high-security?} Start -->|None/Unsure| Default_KDF[HKDF-SHA256<br/>✅ Safe default] BSI_Choice -->|Standard| BSI_HKDF[HKDF-SHA256<br/>✅ Recommended] BSI_Choice -->|High-assurance| BSI_ETSI[CatKDF or CasKDF<br/>✅ Acceptable] ETSI_Choice -->|Standard 5G/6G| ETSI_Cat[CatKDF<br/>✅ Required] ETSI_Choice -->|High-security| ETSI_Cas[CasKDF<br/>✅ Preferred] ETSI_Choice -->|Fallback| ETSI_HKDF[HKDF-SHA256<br/>⚠️ Acceptable] style NIST_KDF fill:#90EE90 style ANSSI_KDF fill:#90EE90 style BSI_HKDF fill:#90EE90 style Default_KDF fill:#90EE90 style ETSI_Cat fill:#87CEEB style ETSI_Cas fill:#87CEEB style BSI_ETSI fill:#87CEEB style ETSI_HKDF fill:#FFE4B5

Quick Reference:

If you need... Use this KDF
NIST compliance (USA) HKDF-SHA256 (only option)
ANSSI compliance (France) HKDF-SHA256 (only option)
BSI compliance (Germany) HKDF-SHA256 (recommended) or CatKDF/CasKDF (acceptable)
ETSI compliance (EU Telecom) CatKDF (standard) or CasKDF (high-security)
Unsure HKDF-SHA256 (safest default)

KDF Selection by Regulation

Regulation Required KDF ANKASecure Support
NIST (USA) HKDF-SHA256 (SP 800-56C) ✅ v3.0+
BSI (Germany) Any secure KDF ✅ HKDF, CatKDF, CasKDF
ANSSI (France) HKDF-SHA256 (conservative) ✅ v3.0+
ETSI (EU Telecom) CatKDF or CasKDF (TS 103 744) ✅ v3.0+

Example:

// For ETSI compliance, use CatKDF or CasKDF:
GenerateCompositeKeySpec spec = new GenerateCompositeKeySpec()
    .setKid("etsi-5g-key")
    .setMode(Mode.HYBRID_KEM_COMBINE)
    .addComponent(ComponentSpec.classical("X25519"))
    .addComponent(ComponentSpec.pqc("ML-KEM-768"))
    .setKdf("CatKDF");  // ETSI-compliant KDF

KeyGenerationResult result = sdk.generateCompositeKey(spec);

Testing Strategy

Unit Testing

Test composite key operations in isolation:

@Test
void testCompositeKeyEncryptionDecryption() {
    String kid = "test-composite-key";

    // Generate
    sdk.generateCompositeKey(
        new GenerateCompositeKeySpec()
            .setKid(kid)
            .setMode(Mode.HYBRID_KEM_COMBINE)
            .addComponent(ComponentSpec.classical("X25519"))
            .addComponent(ComponentSpec.pqc("ML-KEM-768"))
    );

    // Encrypt
    EncryptResult encrypted = sdk.encrypt(kid, "test data");

    // Decrypt
    DecryptResult decrypted = sdk.decrypt(encrypted.getJwe());

    assertEquals("test data", new String(decrypted.getPlaintext()));
}

Integration Testing

Test full workflow with real API:

  1. Generate composite key
  2. Encrypt sample data
  3. Decrypt and verify
  4. Rotate key
  5. Re-encrypt with new key
  6. Cleanup (delete test keys)

Load Testing

Measure performance under production load:

# Benchmark composite key operations
ankasecure-cli benchmark \
  --algorithm HYBRID_KEM_COMBINE \
  --operations 10000 \
  --concurrency 10

Expected: ~200-500 ops/sec for composite keys (vs ~1000 ops/sec for simple keys).


Migration Guide: SIMPLE → COMPOSITE

Step 1: Audit Current Keys

curl -X GET /api/key-management/keys \
  -H "Authorization: Bearer $JWT"

Identify simple keys protecting data with 10+ year retention.

Step 2: Generate Composite Replacements

For each simple key, generate composite equivalent:

# Simple key: ML-KEM-768
# Composite: X25519 + ML-KEM-768
curl -X POST /api/key-management/composite-keys \
  -d '{
    "kid": "composite-replacement-1",
    "mode": "HYBRID_KEM_COMBINE",
    "components": [
      {"role": "classical", "algorithm": "X25519"},
      {"role": "pqc", "algorithm": "ML-KEM-768"}
    ]
  }'

Step 3: Re-Encrypt Data

# Re-encrypt without plaintext exposure
curl -X POST /api/crypto/re-encrypt \
  -d '{
    "sourceKid": "simple-ml-kem-key",
    "targetKid": "composite-replacement-1",
    "jweToken": "eyJhbGci..."
  }'

Step 4: Update Application References

// Before (simple key)
EncryptResult result = sdk.encrypt("simple-ml-kem-key", plaintext);

// After (composite key - same API!)
EncryptResult result = sdk.encrypt("composite-replacement-1", plaintext);

No code changes needed — API is transparent.

Step 5: Retire Old Keys

After confirming all data re-encrypted:

curl -X PATCH /api/key-management/keys/simple-ml-kem-key \
  -d '{"status": "retired"}'

Monitoring and Alerting

Key Health Metrics

Monitor these via API:

  • Usage count vs maxUsageLimit
  • Days until expiration
  • Rotation status (last rotated date)
  • Verification failures (for DUALSIGN)
Metric Threshold Action
Usage >80% of limit Rotate key
Expiration <30 days Schedule rotation
Verification failures >5% of operations Investigate key integrity

Example Query

curl -X GET /api/key-management/keys/composite-key-1/health \
  -H "Authorization: Bearer $JWT"

Response:

{
  "kid": "composite-key-1",
  "usageCount": 850000,
  "maxUsageLimit": 1000000,
  "usagePercentage": 85,
  "daysUntilExpiration": 45,
  "status": "active",
  "recommendation": "ROTATE_SOON"
}

Common Pitfalls and Solutions

Pitfall 1: Mixing Security Levels

Problem: Pairing algorithms with mismatched security levels

Example:

❌ X25519 (Level 3) + ML-KEM-512 (Level 1) = Rejected

Solution: Match security levels within 2 steps:

✅ X25519 (Level 3) + ML-KEM-768 (Level 3) = Accepted
✅ EC-384 (Level 3) + ML-KEM-512 (Level 1) = Accepted (within 2 steps)

Pitfall 2: Wrong KDF for Regulation

Problem: Using CatKDF with ANSSI_HYBRID_ENFORCED template

Example:

❌ Template: ANSSI_HYBRID_ENFORCED
   KDF: CatKDF
   Result: "KDF CatKDF not allowed by ANSSI-RGS-v2"

Solution: Check template requirements:

✅ ANSSI requires HKDF-SHA256 only
✅ ETSI requires CatKDF or CasKDF
✅ NIST requires HKDF-SHA256 only
✅ BSI accepts all three KDFs

Pitfall 3: Standalone PQC Key with Hybrid-Enforced Policy

Problem: Attempting to generate standalone ML-KEM key when BSI_HYBRID_ENFORCED is active

Example:

❌ Policy: BSI_HYBRID_ENFORCED (requireComposite=true)
   Request: Standalone ML-KEM-768
   Result: "Policy BSI-TR-02102-1 requires hybrid keys for ML-KEM"

Solution:

✅ Generate composite key instead:
   POST /api/key-management/composite-keys
   {
     "mode": "HYBRID_KEM_COMBINE",
     "componentAlgorithms": [
       {"role": "classical", "algorithm": "X25519"},
       {"role": "pqc", "algorithm": "ML-KEM-768"}
     ],
     "kdf": "HKDF-SHA256"
   }

✅ OR use hash-based signatures (exempt from hybrid requirement):
   POST /api/key-management/keys
   {
     "kty": "SLH-DSA",
     "alg": "SLH-DSA-SHAKE-128s"
   }

Pitfall 4: Using Level 1 Algorithms with EU Policies

Problem: ML-KEM-512 or ML-DSA-44 rejected by BSI/ANSSI/ETSI templates

Example:

❌ Policy: BSI_HYBRID_ENFORCED (minSecurityLevel=3)
   Request: ML-KEM-512 (Level 1)
   Result: "Algorithm ML-KEM-512 (Level 1) below minimum level 3"

Solution: Use Level 3 or higher:

✅ ML-KEM-768 (Level 3) - Recommended
✅ ML-KEM-1024 (Level 5) - Maximum security

Pitfall 5: DUALSIGN Mode with ETSI Template

Problem: ETSI_HYBRID_ENFORCED only allows HYBRID_KEM_COMBINE mode

Example:

❌ Policy: ETSI_HYBRID_ENFORCED
   Request: mode=DUALSIGN
   Result: "Composite mode DUALSIGN not allowed by ETSI-TS-103-744"

Solution:

✅ Use HYBRID_KEM_COMBINE for ETSI
✅ Use BSI_HYBRID_ENFORCED or ANSSI_HYBRID_ENFORCED if you need DUALSIGN

Hash-Based Signature Exception Explained

Important: Hash-based signatures (SLH-DSA, XMSS, LMS) are exempt from hybrid requirements even with strict policies like BSI_HYBRID_ENFORCED or ANSSI_HYBRID_ENFORCED.

Why the exception?

Hash-based signatures are quantum-resistant by design because their security relies on hash function collision resistance, not mathematical problems vulnerable to Shor's algorithm (like factorization or discrete logarithm).

What this means in practice:

Policy: BSI_HYBRID_ENFORCED (requireComposite=true)

❌ Standalone ML-DSA-65 → REJECTED (lattice-based PQC, hybrid required)
✅ Standalone SLH-DSA-128s → ALLOWED (hash-based, exempt)
✅ Standalone XMSS → ALLOWED (hash-based, exempt)
✅ Standalone LMS → ALLOWED (hash-based, exempt)

Regulatory rationale:

BSI TR-02102-1 and ANSSI guidance state that hash-based signatures can be used standalone because they have decades of security analysis and their quantum resistance is mathematically proven through hash function properties.


Next Steps


Document Version 3.0.0 -- updated December 2025 © 2025 ANKATech Solutions INC. All rights reserved.