Class ReencryptResult
Contains the new JWE token produced by server-side re-encryption from one key to another, along with comprehensive metadata for both the old decryption key and the new encryption key. The plaintext is never exposed to the client during this operation.
Use Cases
- Key rotation for encrypted data without client-side decryption
- Migrating encrypted data to stronger algorithms
- Compliance-driven periodic key rotation
- Transparent key migration for legacy encrypted files
JWE Token Structure
When the new key is a single-recipient key, getJweToken() returns a
Compact JWE (RFC 7516 §7.1) containing five Base64URL segments; when it is
a composite KEM key, the token is the §7.2 General JSON JWE carrying one
recipient per component, which Compact Serialization cannot hold. The Compact
form is:
BASE64URL(ProtectedHeader).
BASE64URL(EncryptedKey).
BASE64URL(IV).
BASE64URL(Ciphertext).
BASE64URL(AuthenticationTag)
Every recipient of the produced JWE
getRecipients() lists every recipient of the re-encrypted JWE, in its order:
the key each one names, the key-material version its content-encryption key was wrapped
to, and that key's algorithm. For a JWE addressed to several keys, the one named by
sourceKid is replaced by the new key at its position and every other recipient
is kept, re-wrapped at its current PRIMARY.
ReencryptResult result = sdk.reencrypt("archive-2026", "custodian-a", multiRecipientJwe);
for (ReencryptedRecipient r : result.getRecipients()) {
System.out.println(r.getKid() + " (" + r.getAlgorithm() + ") v" + r.getMaterialVersion());
}
Migration Mode
The isMigrationMode() flag indicates whether the operation handled
legacy ciphertext without a kid in the header. This is useful for
auditing and tracking migration workflows.
Thread Safety
Instances are effectively immutable after construction. All setters are for internal SDK use during deserialization. Once returned from SDK methods, instances are safe to share across threads.
Example
// Re-encrypt from old key to new key
ReencryptResult result = sdk.reencrypt("new-ml-kem-key", oldJweToken);
System.out.println("Re-encryption complete");
System.out.println("Old key: " + result.getOldKeyRequested() +
" (" + result.getOldKeyAlgorithmUsed() + ")");
System.out.println("New key: " + result.getNewKeyRequested() +
" (" + result.getNewKeyAlgorithmUsed() + ")");
System.out.println("Material versions: " + result.getSourceMaterialVersion() +
" -> " + result.getTargetMaterialVersion());
if (result.isMigrationMode()) {
System.out.println("Migrated legacy ciphertext to managed format");
}
// New JWE token ready for storage
String newJwe = result.getJweToken();
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionReturns the new JWE token after re-encryption.Returns the hybrid algorithm used for encryption.Returns the original key identifier requested for encryption.Returns the hybrid algorithm used for decryption.Returns the original key identifier requested for decryption.List<co.ankatech.secure.client.model.ReencryptedRecipient>Returns every recipient of the re-encrypted JWE, in the JWE's recipient order: the key each one names (kid), the key-material version its content-encryption key was wrapped to (materialVersion), and that key's catalogue algorithm (algorithm).Returns the key-material version that decrypted the original payload under the source Stable KID.Returns the PRIMARY key-material version that encrypted the new payload under the target Stable KID.Returns non-fatal warnings encountered during the re-encryption operation.booleanIndicates whether the operation ran in migration mode.
-
Constructor Details
-
ReencryptResult
public ReencryptResult()
-
-
Method Details
-
getJweToken
Returns the new JWE token after re-encryption.The token contains the same plaintext as the original JWE but encrypted with the new key. It is self-contained and can be stored or transmitted independently.
- Returns:
- the Compact JWE string (five Base64URL segments), or the General JSON JWE
string when the new key is a composite KEM key; never
null
-
getOldKeyRequested
Returns the original key identifier requested for decryption.- Returns:
- non-null old kid
-
getSourceMaterialVersion
Returns the key-material version that decrypted the original payload under the source Stable KID.- Returns:
- source material version;
nullwhen not resolvable — never 0
-
getOldKeyAlgorithmUsed
Returns the hybrid algorithm used for decryption.- Returns:
- non-null algorithm identifier
-
getNewKeyRequested
Returns the original key identifier requested for encryption.- Returns:
- non-null new kid
-
getTargetMaterialVersion
Returns the PRIMARY key-material version that encrypted the new payload under the target Stable KID.- Returns:
- target material version;
nullwhen not resolvable — never 0
-
getNewKeyAlgorithmUsed
Returns the hybrid algorithm used for encryption.- Returns:
- non-null algorithm identifier
-
getRecipients
Returns every recipient of the re-encrypted JWE, in the JWE's recipient order: the key each one names (kid), the key-material version its content-encryption key was wrapped to (materialVersion), and that key's catalogue algorithm (algorithm).A single-recipient JWE lists its one recipient. For a JWE addressed to several keys the new key sits at the position of the replaced recipient and every other recipient is listed with the version it was re-wrapped at.
Example:
ReencryptResult result = sdk.reencryptFileCompact("archive-2026", "custodian-a", Path.of("board-minutes.jwe"), Path.of("board-minutes.rotated.jwe")); result.getRecipients().forEach(r -> log.info("recipient {} v{}", r.getKid(), r.getMaterialVersion()));- Returns:
- the recipients of the produced JWE, unmodifiable, and each call returns fresh copies of the entries, so changing one changes nothing in this result;
nullon the streaming path, whose response carries no recipient list
-
getWarnings
Returns non-fatal warnings encountered during the re-encryption operation.Warnings are type-safe instances that may relate to either the old decryption key or the new encryption key. Use pattern matching for programmatic handling:
ReencryptResult result = sdk.reencrypt("new-key", oldJweToken); if (result.getWarnings() != null && !result.getWarnings().isEmpty()) { for (CryptoWarning warning : result.getWarnings()) { switch (warning) { case KeyExpirationWarning kew -> { logger.warn("Key expiring in {} days - Old: {}, New: {}", kew.daysRemaining(), result.getOldKeyRequested(), result.getNewKeyRequested()); if (kew.severity() == WarningSeverity.CRITICAL) { alertOps("Urgent key rotation needed"); } } case UsageLimitWarning ulw -> logger.warn("{} - {}", ulw.message(), ulw.recommendedAction()); case GenericWarning gw when gw.rawMessage().contains("MIGRATION_MODE") -> auditLog("Migrated legacy ciphertext to managed format"); case GenericWarning gw -> logger.info("Warning: {}", gw.rawMessage()); } } }Common warning types:
KeyExpirationWarning: Old or new key approaching expirationUsageLimitWarning: Usage limits approachingGenericWarning: Migration mode, legacy format notices
- Returns:
- unmodifiable list of warnings (null if no warnings, never empty if non-null)
-
isMigrationMode
public boolean isMigrationMode()Indicates whether the operation ran in migration mode.Returns
trueif the original ciphertext lacked akidin the JWE header and asourceKidwas provided to name the key it was produced for. This is typical for legacy encrypted files.- Returns:
trueif migration mode was used;falsefor normal managed re-encryption
-