Class DecryptVerifyResult

java.lang.Object
co.ankatech.ankasecure.sdk.model.DecryptVerifyResult

public class DecryptVerifyResult extends Object
Result of a decrypt-then-verify combined operation.

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 Separation

The result provides separate metadata for the decryption layer and verification layer, allowing inspection of which keys and algorithms were used at each step.

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();
     System.out.println("Message verified from: " + result.getSigningKey());
     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());
 System.out.println("Signature algorithm: " + result.getSignAlgorithmUsed());
 
Since:
3.0.0
See Also:
  • 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 with DecryptResult.getDecryptedData(), which returns a copy.

      Returns:
      decrypted plaintext bytes; may be null if operation failed
    • setDecryptedData

      public DecryptVerifyResult setDecryptedData(byte[] decryptedData)
      Sets the decrypted plaintext bytes.
      Parameters:
      decryptedData - the plaintext
      Returns:
      this instance for fluent API
    • getDecryptKeyRequested

      public String getDecryptKeyRequested()
      Gets the key identifier requested for decryption.
      Returns:
      requested decrypt key ID
    • setDecryptKeyRequested

      public DecryptVerifyResult setDecryptKeyRequested(String decryptKeyRequested)
      Sets the key identifier requested for decryption.
      Parameters:
      decryptKeyRequested - the key ID
      Returns:
      this instance for fluent API
    • getDecryptMaterialVersion

      public Integer getDecryptMaterialVersion()
      Gets the key-material version (ank_kv) that performed the decryption under the requested Stable KID.
      Returns:
      decrypt material version; null when not resolvable — never 0
    • setDecryptMaterialVersion

      public DecryptVerifyResult setDecryptMaterialVersion(Integer decryptMaterialVersion)
      Sets the key-material version that performed the decryption.
      Parameters:
      decryptMaterialVersion - the material version
      Returns:
      this instance for fluent API
    • getDecryptAlgorithmUsed

      public String getDecryptAlgorithmUsed()
      Gets the algorithm used for decryption.

      Example: "ML-KEM-1024+A256GCM", "RSA-OAEP-256+A256GCM"

      Returns:
      decryption algorithm
    • setDecryptAlgorithmUsed

      public DecryptVerifyResult setDecryptAlgorithmUsed(String decryptAlgorithmUsed)
      Sets the algorithm used for decryption.
      Parameters:
      decryptAlgorithmUsed - the algorithm
      Returns:
      this instance for fluent API
    • getDecryptWarnings

      public List<CryptoWarning> getDecryptWarnings()
      Gets structured warnings related to the decryption operation.

      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 decrypt warnings (never null, may be empty)
    • setDecryptWarnings

      public DecryptVerifyResult setDecryptWarnings(List<CryptoWarning> decryptWarnings)
      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

      public DecryptVerifyResult setSignatureValid(boolean signatureValid)
      Sets whether signature verification succeeded.
      Parameters:
      signatureValid - true if signature is valid
      Returns:
      this instance for fluent API
    • getSigningKey

      public String getSigningKey()
      Gets the key identifier used for signing (from JWS header).
      Returns:
      signing key ID
    • setSigningKey

      public DecryptVerifyResult setSigningKey(String signingKey)
      Sets the key identifier used for signing.
      Parameters:
      signingKey - the key ID
      Returns:
      this instance for fluent API
    • getVerifyMaterialVersion

      public Integer getVerifyMaterialVersion()
      Gets the key-material version (ank_kv) that performed the signature verification under the requested Stable KID.
      Returns:
      verify material version; null when not resolvable — never 0
    • setVerifyMaterialVersion

      public DecryptVerifyResult setVerifyMaterialVersion(Integer verifyMaterialVersion)
      Sets the key-material version that performed the signature verification.
      Parameters:
      verifyMaterialVersion - the material version
      Returns:
      this instance for fluent API
    • getSignAlgorithmUsed

      public String getSignAlgorithmUsed()
      Gets the algorithm used for signing (from JWS header).

      Example: "ML-DSA-87", "ECDSA-P256-SHA256"

      Returns:
      signature algorithm
    • setSignAlgorithmUsed

      public DecryptVerifyResult setSignAlgorithmUsed(String signAlgorithmUsed)
      Sets the algorithm used for signing.
      Parameters:
      signAlgorithmUsed - the algorithm
      Returns:
      this instance for fluent API
    • getSignerInfo

      public String getSignerInfo()
      Gets additional signer information (if present in JWS claims).

      May contain subject, issuer, or other identity claims.

      Returns:
      signer information
    • setSignerInfo

      public DecryptVerifyResult setSignerInfo(String signerInfo)
      Sets additional signer information.
      Parameters:
      signerInfo - the information
      Returns:
      this instance for fluent API
    • getVerifyWarnings

      public List<CryptoWarning> getVerifyWarnings()
      Gets structured warnings related to the signature verification operation.

      Warnings are type-safe instances allowing pattern matching:

      
       for (CryptoWarning warning : result.getVerifyWarnings()) {
           switch (warning) {
               case KeyExpirationWarning kew ->
                   logger.warn("Verification key expires in {} days: {}",
                       kew.daysRemaining(), kew.recommendedAction());
               case UsageLimitWarning ulw when ulw.severity() == WarningSeverity.CRITICAL ->
                   alertSecurityTeam("Verification key usage critical");
               case GenericWarning gw ->
                   logger.info("Verify warning: {}", gw.rawMessage());
           }
       }
       
      Returns:
      unmodifiable list of verify warnings (never null, may be empty)
    • setVerifyWarnings

      public DecryptVerifyResult setVerifyWarnings(List<CryptoWarning> verifyWarnings)
      Sets warnings related to the signature verification operation.
      Parameters:
      verifyWarnings - the warnings
      Returns:
      this instance for fluent API
    • getQualifiedTimestamp

      public QualifiedTimestampInfo getQualifiedTimestamp()
      Returns the embedded RFC 3161 qualified timestamp from the inner JWS, when present.

      Informational only — never affects isSignatureValid(). Returns null when the inner JWS carried no qualified timestamp.

      Returns:
      the qualified-timestamp view, or null when absent
      Since:
      3.0.0
    • setQualifiedTimestamp

      public DecryptVerifyResult setQualifiedTimestamp(QualifiedTimestampInfo qualifiedTimestamp)
      Sets the embedded qualified timestamp from the inner JWS.
      Parameters:
      qualifiedTimestamp - the timestamp view (may be null)
      Returns:
      this instance for fluent API
    • getGcmTagVerdict

      public String getGcmTagVerdict()
      Returns the outer AES-GCM tag integrity dimension of the streaming decrypt-verify result.

      Populated only on the streaming path, which frames a two-verdict trailing part. On the in-memory decryptThenVerify path this is null: an overall valid result already implies BOTH the outer GCM tag AND the inner JWS signature passed (fail-closed both-must-pass gate).

      Returns:
      "VALID" / "INVALID", or null when not surfaced
    • setGcmTagVerdict

      public DecryptVerifyResult setGcmTagVerdict(String gcmTagVerdict)
      Sets the outer AES-GCM tag integrity dimension.
      Parameters:
      gcmTagVerdict - the GCM tag verdict token (may be null)
      Returns:
      this instance for fluent API
    • getSignatureVerdict

      public String getSignatureVerdict()
      Returns the inner JWS signature integrity dimension of the streaming decrypt-verify result.

      Populated only on the streaming path. On the in-memory decryptThenVerify path this is null — see getGcmTagVerdict().

      Returns:
      "VALID" / "INVALID", or null when not surfaced
    • setSignatureVerdict

      public DecryptVerifyResult setSignatureVerdict(String signatureVerdict)
      Sets the inner JWS signature integrity dimension.
      Parameters:
      signatureVerdict - the signature verdict token (may be null)
      Returns:
      this instance for fluent API
    • hasAnyWarnings

      public boolean hasAnyWarnings()
      Checks if there are any warnings (decrypt or verify).
      Returns:
      true if either decryption or verification produced warnings
    • hasDecryptWarnings

      public boolean hasDecryptWarnings()
      Checks if decryption operation produced warnings.
      Returns:
      true if decrypt warnings list is non-empty
    • hasVerifyWarnings

      public boolean hasVerifyWarnings()
      Checks if verification operation produced warnings.
      Returns:
      true if verify warnings 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

      public String toString()
      Returns string representation for debugging.
      Overrides:
      toString in class Object
      Returns:
      debug string