Flow 23 --- RSA-2048 → ML-KEM-768 Immediate Rotation
This scenario shows an instant successor upgrade from a classical RSA-2048 key to a post-quantum ML-KEM-768 key with capability reduction acknowledgment and then proves that the old KID can still be used transparently:
-
Generate an RSA-2048 key capable of
encrypt/decrypt(also supportssign/verify). -
Create an ML-KEM-768 successor in one API call (
createRotation) with explicit acknowledgment that signing capabilities will be lost. -
Encrypt a plaintext with the original RSA KID and watch the platform silently redirect the request to the ML-KEM successor.
Key points
Capability Reduction Handling: RSA-2048 supports 4 operations (encrypt/decrypt/sign/verify), while ML-KEM-768 only supports 2 (encrypt/decrypt). The rotation requires explicit acknowledgment via
setAcknowledgeCapabilityReduction(true).Zero downtime: the old KID stays valid while cryptography is instantly upgraded.
The SDK's response reveals both the key you asked for and the successor actually used.
Works for any successor pair with or without capability reduction (P-384 → ML-KEM-768, RSA-3072 → FALCON-1024, ...).
Perfect fit for brown-field services that must migrate to PQC without touching client code.
When to use it
-
Regulatory cut-overs---move to quantum-safe algorithms overnight yet keep legacy identifiers alive.
-
Gradual roll-outs---encrypt new data with the successor while historical tokens continue to decrypt with the old key.
-
Secrets-rotation policies---rotate keys on schedule (or on compromise) without ever re-encrypting data client-side.
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/ExampleScenario23.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
*/
/* *****************************************************************************
* FILE: ExampleScenario23.java
* ****************************************************************************/
package co.ankatech.ankasecure.sdk.examples;
import co.ankatech.ankasecure.sdk.AnkaSecureSdk;
import co.ankatech.ankasecure.sdk.exception.AnkaSecureSdkException;
import co.ankatech.ankasecure.sdk.model.EncryptResult;
import co.ankatech.ankasecure.sdk.model.KeyGenerationSummarySpec;
import co.ankatech.ankasecure.sdk.model.GenerateKeySpec;
import java.nio.file.Files;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import static co.ankatech.ankasecure.sdk.examples.ExampleUtil.*;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Immediate key rotation from RSA-2048 to ML-KEM-768 with capability reduction
* acknowledgment and transparent successor usage during encryption.
* <p>
* This scenario demonstrates handling capability reduction when rotating from
* RSA (which supports encrypt/decrypt/sign/verify) to ML-KEM (which only
* supports encrypt/decrypt). The rotation requires explicit acknowledgment
* of the loss of signing capabilities.
*
* @author ANKATech – Security Engineering
* @since 2.1.0
*/
public final class ExampleScenario23 {
/* ------------------------------------------------------------------ */
private static final String RSA_KID =
"scenario23_rsa_" + System.currentTimeMillis();
/* ====================================================================== */
public static void main(String[] args) {
System.out.println("===== SCENARIO 23 START =====");
System.out.println("""
Purpose :
* Provision an RSA-2048 key and rotate it to ML-KEM-768.
* Demonstrate capability reduction handling (losing sign/verify).
* Encrypt with original KID and observe successor selection.
Steps :
1) Generate RSA-2048 key (supports: encrypt, decrypt, sign, verify)
2) Rotate to ML-KEM-768 successor (supports: encrypt, decrypt only)
3) Encrypt plaintext using rotated key
--------------------------------------------------------------""");
try {
Files.createDirectories(TEMP_DIR);
Properties props = loadProperties();
AnkaSecureSdk sdk = authenticate(props);
runScenario(sdk);
} catch (Exception ex) {
fatal("Scenario 23 failed", ex);
}
System.out.println("===== SCENARIO 23 END =====");
}
/* ====================================================================== */
private static void runScenario(AnkaSecureSdk sdk)
throws AnkaSecureSdkException {
/* 1 – RSA-2048 key ------------------------------------------------ */
sdk.generateKey(new GenerateKeySpec()
.setKid(RSA_KID)
.setKty("RSA")
.setAlg("RSA-2048")
.setKeyOps(List.of("encrypt", "decrypt")));
System.out.println("[1] RSA-2048 key generated -> kid = " + RSA_KID);
/* 2 – rotate to ML-KEM-768 ------------------------------------- */
String kemKid = "scenario23_mlkem_" + System.currentTimeMillis();
KeyGenerationSummarySpec successor = sdk.createRotation(
RSA_KID,
new GenerateKeySpec()
.setKid(kemKid)
.setKty("ML-KEM")
.setAlg("ML-KEM-768")
.setAcknowledgeCapabilityReduction(true));
// RSA supports sign/verify, ML-KEM does not - acknowledging reduction
Objects.requireNonNull(successor, "Rotation must return successor metadata");
System.out.println("[2] Successor created -> kid = " + successor.getKid());
System.out.println(" Capability reduction acknowledged: sign/verify → (removed)");
/* 3 – encrypt with original KID -------------------------------- */
byte[] plaintext = "Post-rotation encryption demo".getBytes(UTF_8);
EncryptResult enc = sdk.encrypt(RSA_KID, plaintext);
System.out.println("[3] Encryption metadata");
System.out.println(" Key requested : " + nullSafe(enc.getKeyRequested()));
System.out.println(" Key used : " + nullSafe(enc.getActualKeyUsed()));
System.out.println(" Algorithm used : " + nullSafe(enc.getAlgorithmUsed()));
}
private ExampleScenario23() {/* no-instantiation */}
}
How to run
Console milestones
-
RSA-2048 key generated (supports: encrypt, decrypt, sign, verify)
-
ML-KEM-768 successor created with capability reduction acknowledgment (
createRotation) -
Capability reduction acknowledged: sign/verify operations removed
-
Encryption call shows Key requested = RSA KID but Key used = ML-KEM successor
-
Algorithm usedreportsML-KEM-768+...confirming PQC redirect
Where next?
© 2025 ANKATech Solutions INC. All rights reserved.