Class DecryptVerifyResult
Contains the plaintext extracted after decrypting a nested JWE(JWS) token and
verifying the inner JWS signature. This is the inverse of
signThenEncrypt.
Security Model
- Step 1: Decrypt outer JWE layer to reveal inner JWS
- Step 2: Verify inner JWS signature for authenticity
- Result: Verified plaintext with sender authentication
Critical: Signature Validation
ALWAYS check isSignatureValid() before trusting the plaintext.
Decryption can succeed even if the signature is invalid, which may indicate tampering
or forgery.
Metadata
The decryption layer is described by the key the outer JWE was decrypted with
(getDecryptKeyRequested(), getDecryptMaterialVersion(),
getDecryptAlgorithmUsed()). The verification layer is described per signer:
getSignatureResults() holds one entry per signature of the inner JWS, in token
order - one for an inner JWS signed by one key, N for one signed by N keys.
Streaming Variant
The buffered
decryptThenVerifyFileStream
variant writes the verified plaintext directly to the destination file (bounded memory, never
buffered in the result), so on that path getDecryptedData() is null even though
isSignatureValid() is true — the isSignatureValid → getDecryptedData idiom
shown above applies to the in-memory paths (decryptThenVerify). The streaming path additionally surfaces the two integrity dimensions via
getGcmTagVerdict() / getSignatureVerdict().
Thread Safety
Instances are mutable during construction but should be treated as effectively immutable after being returned by SDK methods.
Example
DecryptVerifyResult result = sdk.decryptThenVerify(jweToken);
if (result.isSignatureValid()) {
byte[] plaintext = result.getDecryptedData();
result.getSignatureResults().forEach(s ->
System.out.println("Signed by: " + s.getKid() + " v" + s.getMaterialVersion()));
System.out.println("Content: " + new String(plaintext, StandardCharsets.UTF_8));
} else {
System.out.println("WARNING: Signature invalid - do not trust this message");
// Log security incident
}
// Inspect metadata
System.out.println("Decrypted with: " + result.getDecryptKeyRequested()
+ " material version " + result.getDecryptMaterialVersion());
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionGets the algorithm used for decryption.byte[]Returns the decrypted plaintext bytes.Gets the key identifier requested for decryption.Gets the key-material version (ank_kv) that performed the decryption under the requested Stable KID.Gets structured warnings from the decryption and from the verification of every inner signature.Returns the outer AES-GCM tag integrity dimension of the streaming decrypt-verify result.Returns the embedded RFC 3161 qualified timestamp from the inner JWS, when present.List<co.ankatech.secure.client.model.SignatureResult>Returns the verification detail of every signature of the inner JWS, in token order (RFC 7515 §7.2.1): the key each signature names, that key's catalogue algorithm, the key-material version it resolved to, and whether it verified.Returns the inner JWS signature integrity dimension of the streaming decrypt-verify result.booleanChecks if the operation produced any warning (decryption or verification).booleanChecks if the warning list is non-empty.booleanChecks if operation completed successfully with no issues.booleanChecks if the signature verification succeeded.setDecryptAlgorithmUsed(String decryptAlgorithmUsed) Sets the algorithm used for decryption.setDecryptedData(byte[] decryptedData) Sets the decrypted plaintext bytes.setDecryptKeyRequested(String decryptKeyRequested) Sets the key identifier requested for decryption.setDecryptMaterialVersion(Integer decryptMaterialVersion) Sets the key-material version that performed the decryption.setDecryptWarnings(List<CryptoWarning> decryptWarnings) Sets warnings related to the decryption operation.setGcmTagVerdict(String gcmTagVerdict) Sets the outer AES-GCM tag integrity dimension.setQualifiedTimestamp(QualifiedTimestampInfo qualifiedTimestamp) Sets the embedded qualified timestamp from the inner JWS.setSignatureResults(List<co.ankatech.secure.client.model.SignatureResult> signatureResults) Sets the per-signature verification detail of the inner JWS.setSignatureValid(boolean signatureValid) Sets whether signature verification succeeded.setSignatureVerdict(String signatureVerdict) Sets the inner JWS signature integrity dimension.toString()Returns string representation for debugging.
-
Constructor Details
-
DecryptVerifyResult
public DecryptVerifyResult()Default constructor initializing empty warning lists.
-
-
Method Details
-
getDecryptedData
public byte[] getDecryptedData()Returns the decrypted plaintext bytes.Security Warning: Always check
isSignatureValid()before trusting this data. Invalid signatures may indicate tampering.Note: Returns the internal array directly (no defensive copy). Callers who need to mutate or retain the result should copy it via
Arrays.copyOf(result.getDecryptedData(), ...). Contrast withDecryptResult.getDecryptedData(), which returns a copy.- Returns:
- decrypted plaintext bytes; may be
nullif operation failed
-
setDecryptedData
Sets the decrypted plaintext bytes.- Parameters:
decryptedData- the plaintext- Returns:
- this instance for fluent API
-
getDecryptKeyRequested
Gets the key identifier requested for decryption.Server-supplied and unrendered: display it through
InertText.text(String).- Returns:
- requested decrypt key ID
-
setDecryptKeyRequested
Sets the key identifier requested for decryption.- Parameters:
decryptKeyRequested- the key ID- Returns:
- this instance for fluent API
-
getDecryptMaterialVersion
Gets the key-material version (ank_kv) that performed the decryption under the requested Stable KID.- Returns:
- decrypt material version;
nullwhen not resolvable — never 0
-
setDecryptMaterialVersion
Sets the key-material version that performed the decryption.- Parameters:
decryptMaterialVersion- the material version- Returns:
- this instance for fluent API
-
getDecryptAlgorithmUsed
Gets the algorithm used for decryption.Example: "ML-KEM-1024", "X25519+ML-KEM-768" (the decrypting key's catalogue algorithm)
Server-supplied and unrendered: display it through
InertText.text(String).- Returns:
- decryption algorithm
-
setDecryptAlgorithmUsed
Sets the algorithm used for decryption.- Parameters:
decryptAlgorithmUsed- the algorithm- Returns:
- this instance for fluent API
-
getDecryptWarnings
Gets structured warnings from the decryption and from the verification of every inner signature.Warnings are type-safe instances allowing pattern matching:
for (CryptoWarning warning : result.getDecryptWarnings()) { switch (warning) { case KeyExpirationWarning kew when kew.severity() == WarningSeverity.CRITICAL -> logger.error("URGENT: Decryption key expires in {} days", kew.daysRemaining()); case UsageLimitWarning ulw -> planKeyRotation(ulw); case GenericWarning gw -> logger.info("Decrypt warning: {}", gw.rawMessage()); } }- Returns:
- unmodifiable list of warnings of both layers (never null, may be empty)
-
setDecryptWarnings
Sets warnings related to the decryption operation.- Parameters:
decryptWarnings- the warnings- Returns:
- this instance for fluent API
-
isSignatureValid
public boolean isSignatureValid()Checks if the signature verification succeeded.Critical: Always check this before trusting the plaintext. Decryption can succeed even if signature is invalid.
- Returns:
- true if signature verification passed
-
setSignatureValid
Sets whether signature verification succeeded.- Parameters:
signatureValid- true if signature is valid- Returns:
- this instance for fluent API
-
getSignatureResults
Returns the verification detail of every signature of the inner JWS, in token order (RFC 7515 §7.2.1): the key each signature names, that key's catalogue algorithm, the key-material version it resolved to, and whether it verified.One entry for an inner JWS signed by one key; N entries for one signed by N keys. A successful response is returned only when every signature verified, so on the in-memory path every entry reports
verified = true.Example:
DecryptVerifyResult result = sdk.decryptThenVerify(jweToken); for (SignatureResult signer : result.getSignatureResults()) { audit.record(signer.getKid(), signer.getAlgorithm(), signer.getMaterialVersion()); }- Returns:
- unmodifiable list of per-signature entries (never null, may be empty when the server returned none); each call returns fresh copies of the entries, so changing one changes nothing in this result
-
setSignatureResults
public DecryptVerifyResult setSignatureResults(List<co.ankatech.secure.client.model.SignatureResult> signatureResults) Sets the per-signature verification detail of the inner JWS.- Parameters:
signatureResults- the entries, in token order (may benull)- Returns:
- this instance for fluent API
-
getQualifiedTimestamp
Returns the embedded RFC 3161 qualified timestamp from the inner JWS, when present.Informational only — never affects
isSignatureValid(). Returnsnullwhen the inner JWS carried no qualified timestamp.- Returns:
- the qualified-timestamp view, or
nullwhen absent
-
setQualifiedTimestamp
Sets the embedded qualified timestamp from the inner JWS.- Parameters:
qualifiedTimestamp- the timestamp view (may benull)- Returns:
- this instance for fluent API
-
getGcmTagVerdict
Returns the outer AES-GCM tag integrity dimension of the streaming decrypt-verify result.Populated only on the
streamingpath, which frames a two-verdict trailing part. On the in-memorydecryptThenVerifypath this isnull: an overallvalidresult already implies BOTH the outer GCM tag AND the inner JWS signature passed (fail-closed both-must-pass gate).Server-supplied and unrendered: display it through
InertText.text(String).- Returns:
"VALID"/"INVALID", ornullwhen not surfaced
-
setGcmTagVerdict
Sets the outer AES-GCM tag integrity dimension.- Parameters:
gcmTagVerdict- the GCM tag verdict token (may benull)- Returns:
- this instance for fluent API
-
getSignatureVerdict
Returns the inner JWS signature integrity dimension of the streaming decrypt-verify result.Populated only on the
streamingpath. On the in-memorydecryptThenVerifypath this isnull— seegetGcmTagVerdict().Server-supplied and unrendered: display it through
InertText.text(String).- Returns:
"VALID"/"INVALID", ornullwhen not surfaced
-
setSignatureVerdict
Sets the inner JWS signature integrity dimension.- Parameters:
signatureVerdict- the signature verdict token (may benull)- Returns:
- this instance for fluent API
-
hasAnyWarnings
public boolean hasAnyWarnings()Checks if the operation produced any warning (decryption or verification).- Returns:
- true if the warning list is non-empty
-
hasDecryptWarnings
public boolean hasDecryptWarnings()Checks if the warning list is non-empty. The server reports the warnings of the decryption and of every inner signature's verification in that one list.- Returns:
- true if the warning list is non-empty
-
isCompleteSuccess
public boolean isCompleteSuccess()Checks if operation completed successfully with no issues.Success means: signature valid AND no warnings.
- Returns:
- true if signature is valid and no warnings exist
-
toString
Returns string representation for debugging.
-