Class AuthenticatedSdk
- All Implemented Interfaces:
AutoCloseable
This class represents an authenticated session with the ANKASecure© API. Each instance is bound to a specific JWT access token and provides all cryptographic operations available to that authenticated identity.
Thread Safety
Fully thread-safe. Instances are immutable and can be safely shared across thousands of concurrent threads. The underlying HTTP client uses connection pooling and HTTP/2 multiplexing for efficient resource usage.
Lifecycle Management
Instances are created by AnkaSecureSdk.authenticate(),
AnkaSecureSdk.authenticateApplication(String, co.ankatech.ankasecure.sdk.security.SecretChars)
or AnkaSecureSdk.authenticateApplicationWithKeyPair(String, co.ankatech.ankasecure.sdk.security.ClientAssertionSigner, String).
They remain valid until the token expires. Use isTokenExpiredLocally() to check validity.
Token Expiry Handling
AuthenticatedSdk sdk = factory.authenticateApplication(clientId, clientSecret);
// Use for multiple operations
EncryptResult r1 = sdk.encrypt("key1", data1);
EncryptResult r2 = sdk.encrypt("key2", data2);
// Check expiry before long-running tasks
if (sdk.isTokenExpiredLocally()) {
sdk = factory.authenticateApplication(clientId, clientSecret);
}
// Continue with new token
EncryptResult r3 = sdk.encrypt("key3", data3);
Concurrent Usage Pattern
// Single AuthenticatedSdk shared across all threads
AuthenticatedSdk sdk = factory.authenticateApplication(clientId, clientSecret);
// Virtual threads (Java 21+) - 10,000+ concurrent operations
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
List<CompletableFuture<EncryptResult>> futures = dataList.stream()
.map(data -> CompletableFuture.supplyAsync(
() -> sdk.encrypt("my-key", data),
executor
))
.toList();
List<EncryptResult> results = futures.stream()
.map(CompletableFuture::join)
.toList();
}
Memory Characteristics
- Instance size: ~250 bytes (token string + references)
- Shared HTTP client: single connection pool across all instances
- 10,000 instances: ~2.5 MB total overhead
File-Output Overwrite Policy
Every file-output method (the *File, *FileCompact, *FileStream and
combined/migration families) quarantines its result to a sidecar (<output>.part) and
atomically renames it onto output. By default
(OverwritePolicy.FAIL_IF_EXISTS) an operation fails if output already exists,
throwing DestinationExistsException and leaving the
pre-existing file untouched. To replace an existing destination, derive an overwrite-enabled
instance with withOverwrite() (or
withOverwritePolicy(OverwritePolicy.OVERWRITE)); the
derived instance shares this instance's JWT and HTTP client with no re-authentication.
A failure of the caller's own files — an input that is missing or unreadable, a result or
working file that cannot be written or moved into place — is reported by every file method as
LocalFileException, naming the file and whether it
had to be read or written. It is never classified as a network failure
(IO /
TIMEOUT).
Stateful Signing Keys
A stateful hash-based key (XMSS, XMSS^MT, LMS/HSS) holds a finite number of one-time
signatures and the server spends one per signature. Every method that produces a signature
— sign*, signThenEncrypt*, resign* (with the new key) and
convertPkcs7ToJose* — can therefore be refused with an HTTP 409 carrying one
of two error codes:
SdkErrorCode.STATEFUL_KEY_EXHAUSTED— permanent for that key: it has no one-time signature left, or it predates a database restore. Rotate the key; retrying is refused again. The signatures it already produced still verify.SdkErrorCode.STATEFUL_KEY_BUSY— transient: another request is reserving the key's next signature. Retry afterAnkaSecureSdkException.getRetryAfterSeconds()seconds.
Either refusal is decided before any output exists: a file method writes no result. On a streaming route and on the PKCS#7 conversion the one-time signature is reserved before the request body is processed, so a request then refused for its body spends one index without producing a signature.
-
Method Summary
Modifier and TypeMethodDescriptionco.ankatech.secure.client.model.Pkcs7AnalysisResponseanalyzePkcs7(co.ankatech.secure.client.model.Pkcs7AnalysisRequest request) Analyzes a PKCS#7 file to extract metadata and certificate information.co.ankatech.secure.client.model.Pkcs7AnalysisResponseanalyzePkcs7Stream(File file) Analyzes a PKCS#7 file using streaming to avoid loading the entire file into memory.voidclose()Clears the bearer token from the underlyingAnkaSecureOpenApiClient'sHttpBearerAuth.co.ankatech.secure.client.model.Pkcs7ConversionResponseconvertPkcs7ToJose(co.ankatech.secure.client.model.Pkcs7ConversionRequest request) Converts a PKCS#7 signature to JOSE (JWS) format.convertPkcs7ToJoseStream(co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest metadata, File inputFile, File outputFile) Converts a PKCS#7 signature to JOSE using streaming.Decrypts a JWE (RFC 7516) token to recover the original plaintext.Decrypts a JWE token string with the recipient the caller names.decryptFile(String recipientKid, Path input, Path output) Decrypts a file of any format with the recipient the caller names, selecting the path from the input's actual format exactly asdecryptFile(Path, Path)does.decryptFile(Path input, Path output) Decrypts a file.decryptFileCompact(String recipientKid, Path input, Path output) Decrypts a Compact or General JSON JWE file with the recipient the caller names.decryptFileCompact(Path input, Path output) Decrypts a file with forced compact format.decryptFileStream(String recipientKid, Path input, Path output) Decrypts a streaming JWET file with the recipient the caller names; sent as therecipientKidquery parameter of/crypto/stream/decrypt.decryptFileStream(Path input, Path output) Decrypts a file with forced streaming format.decryptThenVerify(String jweToken) Decrypts a JWE then verifies the inner JWS signature.decryptThenVerify(String recipientKid, String jweToken) Decrypts a nested JWE(JWS) token with the recipient the caller names, then verifies every signature of the inner JWS.decryptThenVerifyFileCompact(String recipientKid, Path input, Path output) Decrypts a nested JWE(JWS) file with the recipient the caller names, then verifies every signature of the inner JWS.decryptThenVerifyFileCompact(Path input, Path output) Decrypts and verifies a nested JWE(JWS) file with forced compact format.decryptThenVerifyFileStream(String recipientKid, Path input, Path output) Decrypts a nested JWE(JWS) streaming artifact with the recipient the caller names, then verifies every signature of the inner JWS;recipientKidis sent as the query parameter of/crypto/stream/decrypt-verify.decryptThenVerifyFileStream(Path input, Path output) Decrypts a nested JWE(JWS) file then verifies the inner signature in streaming mode — the large-file counterpart ofdecryptThenVerifyFileCompact(Path, Path), and the inverse ofsignThenEncryptFileStream(String, String, Path, Path).Encrypts raw bytes using the key identified bykid.encryptFile(String kid, Path input, Path output) Encrypts a file.encryptFileCompact(String kid, Path input, Path output) Encrypts a file with forced compact format, i.e. in one non-streaming request.encryptFileStream(String kid, Path input, Path output) Encrypts a file with forced streaming format.Encrypts a file using a provided public key (without requiring key in ANKASecure).Returns the compact-crypto limit this instance applies, and where it came from.getKeyMetadata(String kid) Retrieves metadata for a specific key.Retrieves the complete list of cryptographic algorithms supported by the server.Retrieves cryptographic algorithms matching the specified filter criteria.Extracts the expiration time from the JWT token.booleanisClosed()booleanChecks whether the access token has expired, or is about to, according to its localexpclaim only.listAllKeys(KeyFilters filters) Lists ALL keys matching the filters by auto-paginating through the server's paginated listing (the AWS-CLI pattern: the API pages, the client iterates).listKeys(KeyFilters filters, int page, int size) Lists ONE PAGE of the keys accessible to the authenticated client.Returns the file-output overwrite policy in effect for this instance.performMigrationWorkflow(File pkcs7File, co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest conversionRequest, File outputFile) Performs a complete PKCS#7-to-JOSE migration workflow with analysis and conversion.Re-encrypts data with a different key without decrypting to plaintext.Re-encrypts a JWE tonewKid, replacing the recipient the caller names.reencryptFile(String newKid, String sourceKid, Path input, Path output) Re-encrypts a file of any format tonewKid, replacing the recipient the caller names, and selecting the path from the input's actual format exactly asreencryptFile(String, Path, Path)does.reencryptFile(String newKid, Path input, Path output) Re-encrypts a file.reencryptFileCompact(String newKid, String sourceKid, Path input, Path output) Re-encrypts a Compact or General JSON JWE file tonewKid, replacing the recipient the caller names.reencryptFileCompact(String newKid, Path input, Path output) Re-encrypts a file with forced compact format.reencryptFileStream(String newKid, String sourceKid, Path input, Path output) Re-encrypts a file with forced streaming format.Re-signs data with a different key without verifying the original signature.resign(String newKid, String jws, JwsSerialization serialization) Re-signs a JWS, explicitly selecting the JWS serialization.Re-signs a JWS withnewKid, replacing the signature of the signer the caller names.resign(String newKid, String sourceKid, String jws, JwsSerialization serialization) Re-signs a JWS withnewKid, replacing the signature of the signer the caller names and selecting the JWS serialization.resignFileCompact(String newKid, String sourceKid, Path input, Path output) Re-signs a JWS file withnewKid, replacing the signature of the signer the caller names.resignFileCompact(String newKid, String sourceKid, Path input, Path output, JwsSerialization serialization) Re-signs a JWS file withnewKid, replacing the signature of the signer the caller names and selecting the JWS serialization.resignFileCompact(String newKid, Path input, Path output) Re-signs a compact JWS file with forced compact format.resignFileCompact(String newKid, Path input, Path output, JwsSerialization serialization) Re-signs a JWS file (attached), explicitly selecting the JWS serialization.Re-signs a detached JWS in streaming mode, naming the signer whose signature is replaced; sent as thesourceKidmember of the/crypto/stream/resignmetadata part.resignFileStream(Path oldJwsHeader, String newKid, String sourceKid, Path input, Path output, SignOptions options) Re-signs a file in streaming mode with options for the new signature.resignFileStream(Path oldJwsHeader, String newKid, Path input, Path output) Re-signs a detached JWS signature with forced streaming format.Signs raw bytes using the key identified bykid.sign(String kid, byte[] data, JwsSerialization serialization) Signs raw bytes, explicitly selecting the JWS serialization.sign(String kid, byte[] data, JwsSerialization serialization, SignOptions options) Signs raw bytes with an explicit serialization and signature options.Signs a file.signFileCompact(String kid, Path input, Path output) Signs a file with forced compact format.signFileCompact(String kid, Path input, Path output, JwsSerialization serialization) Signs a file (attached), explicitly selecting the JWS serialization.signFileCompact(String kid, Path input, Path output, JwsSerialization serialization, SignOptions options) Signs a file (attached) with an explicit serialization and signature options.signFileStream(String kid, Path input, Path output) Signs a file with forced streaming format.signThenEncrypt(String signKid, String encryptKid, byte[] data) Signs then encrypts data in a single operation (nested JWE containing JWS).signThenEncrypt(String signKid, String encryptKid, byte[] data, JwsSerialization serialization) Signs then encrypts, explicitly selecting the inner-JWS serialization.signThenEncrypt(String signKid, String encryptKid, byte[] data, JwsSerialization serialization, SignOptions options) Signs then encrypts data with an explicit inner serialization and options for the inner signature.signThenEncryptFileCompact(String signKid, String encryptKid, Path input, Path output) Signs then encrypts a file with forced compact format.signThenEncryptFileCompact(String signKid, String encryptKid, Path input, Path output, JwsSerialization serialization) Signs a file then encrypts it, explicitly selecting the inner-JWS serialization.signThenEncryptFileCompact(String signKid, String encryptKid, Path input, Path output, JwsSerialization serialization, SignOptions options) Signs then encrypts a file (compact) with an explicit inner serialization and options for the inner signature.signThenEncryptFileStream(String signKid, String encryptKid, Path input, Path output) Signs a file then encrypts it in streaming mode (nested JWE(JWS), bounded memory) — the large-file counterpart ofsignThenEncryptFileCompact(String, String, Path, Path).signThenEncryptFileStream(String signKid, String encryptKid, Path input, Path output, SignEncryptStreamOptions options) Signs then encrypts a file in streaming mode with options: the inner signature's validity and the advisory flavor hint, sent in the request's metadata part.verifySignature(String jws) Verifies an attached JWS (RFC 7515) signature held in memory.verifySignature(Path jwsFile) Verifies a JWS signature from a file, accepting either the compact form or the JWS-JSON form (serialization-agnostic).verifySignatureStream(Path dataFile, Path signatureFile) Verifies a detached JWS signature with forced streaming format.verifySignatureUtilityStream(String kty, String alg, String publicKeyB64, String signatureB64, Path dataFile) Verifies a signature using a provided public key (without requiring key in ANKASecure).Convenience wither equivalent towithOverwritePolicy(OverwritePolicy.OVERWRITE): returns a NEW immutableAuthenticatedSdkwhose file-output operations atomically replace an existing destination.withOverwritePolicy(OverwritePolicy overwritePolicy) Returns a NEW immutableAuthenticatedSdkthat appliesoverwritePolicyto every file-output operation, sharing this instance's JWT and HTTP client.
-
Method Details
-
close
public void close()Clears the bearer token from the underlyingAnkaSecureOpenApiClient'sHttpBearerAuth. After this call:- Subsequent operations on this instance throw
IllegalStateException. - The bearer token is no longer reachable via the OkHttp request chain.
Idempotent. Use try-with-resources for deterministic cleanup:
try (AuthenticatedSdk sdk = factory.authenticateApplication(clientId, clientSecret)) { sdk.encrypt(kid, data); } // close() runs here, clearing the bearer tokenNote: the
accessTokenfield is aString(immutable, interned-eligible) and cannot be reliably zeroized — a known JVM-level limitation.close()reduces the in-memory lifetime by clearing the OkHttp interceptor reference, but theStringitself remains until GC.Wither ownership
Instances derived via
withOverwritePolicy(OverwritePolicy)/withOverwrite()SHARE the root's single bearer token and HTTP client. Only the factory-created ROOT owns the token: closing a DERIVED instance marks that instance closed but MUST NOT clear the token still in use by the root (and by any sibling derived instance), preventing a use-after-free of a zeroized secret. Closing the ROOT clears the shared token, ending the session for all views.- Specified by:
closein interfaceAutoCloseable
- Subsequent operations on this instance throw
-
overwritePolicy
Returns the file-output overwrite policy in effect for this instance.- Returns:
- the
OverwritePolicy(defaultOverwritePolicy.FAIL_IF_EXISTS) - See Also:
-
withOverwritePolicy
Returns a NEW immutableAuthenticatedSdkthat appliesoverwritePolicyto every file-output operation, sharing this instance's JWT and HTTP client.This is a pure, local, immutable derivation: it performs NO network round-trip and NO re-authentication. The derived instance shares the SAME JWT reference and the SAME HTTP client (there is no plaintext copy of the token). Per the wither ownership model, only the original factory-created instance owns the token —
closingthe derived instance never clears the token still in use by the original.- Parameters:
overwritePolicy- the overwrite policy for the derived instance; must not benull- Returns:
- a distinct immutable instance with the requested policy; never
null - Throws:
NullPointerException- ifoverwritePolicyisnull- See Also:
-
withOverwrite
Convenience wither equivalent towithOverwritePolicy(OverwritePolicy.OVERWRITE): returns a NEW immutableAuthenticatedSdkwhose file-output operations atomically replace an existing destination.Like
withOverwritePolicy(OverwritePolicy), this performs NO network round-trip and NO re-authentication and shares the same JWT and HTTP client (see the wither ownership model).- Returns:
- a distinct immutable instance with
OverwritePolicy.OVERWRITE; nevernull - See Also:
-
isClosed
public boolean isClosed()- Returns:
trueifclose()has been called; never throws
-
isTokenExpiredLocally
public boolean isTokenExpiredLocally()Checks whether the access token has expired, or is about to, according to its localexpclaim only.This is a local, offline check. It extracts the
expclaim from the JWT payload and compares it with the current time; it does NOT contact the server and therefore does NOT detect server-side revocation — a token that was revoked (logout / blacklist) or superseded by the subject's revocation epoch (bulk revoke, e.g. an admin force-reset, a suspend/delete, or a role scope shrink) is still unexpired locally and returnsfalsehere while the server rejects it. To detect that case, perform an operation and handleTokenRevokedException(thrown on a 401), then re-authenticate.Usage Pattern
AuthenticatedSdk sdk = factory.authenticateApplication(id, clientSecret); // Before an expensive batch operation, cheaply skip a definitely-expired token if (sdk.isTokenExpiredLocally()) { sdk = factory.authenticateApplication(id, clientSecret); } try { processBatch(sdk, largeDataset); } catch (TokenRevokedException revoked) { // The server rejected the still-unexpired token — re-authenticate and retry. sdk = factory.authenticateApplication(id, clientSecret); }Clock skew
A token expiring within 60 seconds is already reported as expired. The comparison is deliberately not exact: the caller's clock and the server's clock are not the same clock, and a token still has to survive the flight time of the operation this check was performed for. Reporting a token with a second left as usable would produce a 401 at the server that is indistinguishable from a revocation, which is the harder failure to diagnose. The window matches the platform's own token refresh window and the clock-skew tolerance it admits on a client assertion.
- Returns:
trueif the token is malformed, already past itsexp, or expiring within the 60-second skew window;falseif it is still comfortably valid by its localexpclaim (which does not imply the server will accept it)
-
getTokenExpiration
Extracts the expiration time from the JWT token.Decodes the JWT payload (Base64URL) and reads the
expclaim (seconds since Unix epoch). Returnsnullif the token is malformed.- Returns:
- the token expiration as
Instant, ornullif malformed
-
encrypt
Encrypts raw bytes using the key identified bykid.The key type determines the algorithm automatically: asymmetric keys (ML-KEM, RSA, ECC) perform key encapsulation + symmetric encryption; symmetric keys (AES) encrypt directly. The result is a JWE (RFC 7516) string containing the ciphertext and all metadata needed for decryption, in the serialization that carries every recipient the server returned:
- Single-recipient key (every non-composite key): Compact Serialization (§7.1), five dot-separated base64url segments.
- Composite KEM key: General JSON Serialization (§7.2), one recipient per component. Compact Serialization holds exactly one recipient, so it cannot represent this result.
decrypt(String)accepts either form.This method is suitable for in-memory payloads up to ~100 MB. For larger files, use
encryptFileStream(String, Path, Path)to avoid loading the entire payload into memory.Example
byte[] plaintext = "Sensitive data".getBytes(StandardCharsets.UTF_8); EncryptResult result = sdk.encrypt("my-ml-kem-768-key", plaintext); // The JWE token is self-contained and can be stored or transmitted String jweToken = result.getJweToken(); // Decrypt later DecryptResult decrypted = sdk.decrypt(jweToken); byte[] recovered = decrypted.getDecryptedData();- Parameters:
kid- key identifier referencing a key stored in ANKASecure©; must not benullplaintext- the raw bytes to encrypt; must not benull- Returns:
- encryption result containing the JWE token (Compact for a single-recipient
key, General JSON for a composite KEM key) and operation metadata;
never
null - Throws:
AnkaSecureSdkException- if the key identified bykiddoes not exist, does not support encryption, the authenticated client lacks permission, or the server returns an errorNullPointerException- ifkidorplaintextisnull- See Also:
-
encryptFileCompact
public EncryptResult encryptFileCompact(String kid, Path input, Path output) throws AnkaSecureSdkException Encrypts a file with forced compact format, i.e. in one non-streaming request. Use when you need a single-line string for API/JSON transmission. Fails if the input exceeds the server's configured compact limit (maxPlaintextBytes, default 4 MB).When to Use Compact Format
- API transmission: JSON responses, HTTP headers, query parameters
- Storage: Single database field (text/varchar)
- Interoperability: JWE standard format (RFC 7516)
Output Format
eyJhbGc...header...XVCJ9.eyJkYXRh...encrypted-payload...9.dBjftJ...tag...
Single-line base64url string, suitable for text-based transmission. That is the RFC 7516 §7.1 Compact Serialization, written for every single-recipient key. A composite KEM key yields one recipient per component, which Compact Serialization cannot hold, so the file then carries the single-line RFC 7516 §7.2 General JSON Serialization instead.
decryptFile(Path, Path)anddecryptFileCompact(Path, Path)read either form.Alternative Methods
- Use
encryptFile(String, Path, Path)for automatic format selection (recommended) - Use
encryptFileStream(String, Path, Path)for large files (above the server's configured compact limit)
Example
// Encrypt small document for API transmission EncryptResult result = sdk.encryptFileCompact( "my-ml-kem-key", Path.of("contract.pdf"), Path.of("contract.jwe") ); System.out.println("Algorithm: " + result.getAlgorithmUsed());- Parameters:
kid- key identifier for encryption; must not benullinput- input file (up to the server's configured compact limit, default 4 MB); must not benulloutput- output file (.jwe recommended); receives the Compact JWE, or the General JSON JWE for a composite KEM key; must not benull- Returns:
- encryption result with metadata; its
jweTokenis exactly what was written; nevernull - Throws:
AnkaSecureSdkException- if the input exceeds the server's configured compact limit (HTTP 413) or operation fails- See Also:
-
encryptFile
Encrypts a file. Recommended for most use cases. Automatically selects the optimal format based on the server-discovered compact payload limit (below the limit = compact, at or above = streaming).This method automatically selects the optimal format:
- Files below the server's
maxPlaintextBytes: a single-line JWE string - Files at or above that limit: Streaming JWE format (binary chunks)
Output Format Below the Limit
The file holds the JWE the server returned, in the serialization that carries all of it:
- Single-recipient key (every non-composite key): RFC 7516 §7.1 Compact Serialization, five dot-separated base64url segments.
- Composite KEM key: RFC 7516 §7.2 General JSON Serialization, a JSON
object with one entry in
recipientsper component. Compact Serialization holds exactly one recipient and cannot represent it.
decryptFile(Path, Path)reads either form, telling them apart by content.Why Use This Method?
You don't need to worry about file sizes or server limits. The threshold is discovered from the server (not hardcoded) and cached briefly; if a compact request is still rejected as too large (HTTP 413) the SDK transparently retries via streaming, ensuring your encryption always succeeds regardless of file size. With PQC transport enabled the SDK never moves to the TLS-only streaming route on its own: an oversized payload is refused with a hint to call the streaming operation, and only a 413 encrypted under the session key still falls back.
When to Use Explicit Formats
Use
encryptFileCompact(String, Path, Path)orencryptFileStream(String, Path, Path)only when you specifically need a particular output format (e.g., compact JWE for API transmission).Example
// Encrypt any file - works for both small and large files EncryptResult result = sdk.encryptFile( "my-ml-kem-key", Path.of("data.bin"), Path.of("data.jwe") ); System.out.println("Encrypted with: " + result.getAlgorithmUsed());- Parameters:
kid- key identifier for encryption; must not benullinput- input file (any size); must not benulloutput- output file (.jwe or .jwet): Compact JWE, General JSON JWE (composite KEM key) or streaming JWET, as described above; must not benull. By default fails ifoutputexists; callwithOverwrite()to overwrite.- Returns:
- encryption result with metadata; never
null - Throws:
AnkaSecureSdkException- if operation failsLocalFileException- if the input cannot be read or the output cannot be writtenDestinationExistsException- ifoutputalready exists and this instance usesOverwritePolicy.FAIL_IF_EXISTS(the default)PqcTransportException- (STREAMING_NOT_CHOSEN) with PQC transport enabled, when the payload is at or above the advertised compact limit or a compact request is refused as too large in any response the session key did not authenticate: the streaming route is protected by TLS only, so the SDK does not choose it on its own. CallencryptFileStream(String, Path, Path)explicitly to use it.- See Also:
- Files below the server's
-
encryptFileStream
public EncryptResult encryptFileStream(String kid, Path input, Path output) throws AnkaSecureSdkException Encrypts a file with forced streaming format. Use for large files (100MB+), low-memory environments, or when binary output is acceptable.When to Use Streaming Format
- Large files: Files above the server's configured compact limit (required), optimal for 100MB+ (recommended)
- Memory constraints: Low-memory environments or embedded systems
- Binary output: When base64 encoding overhead is undesirable
- Progressive processing: Start processing before full upload
Output Format
Binary streaming format (.jwet file) with multipart chunks. Not suitable for text-based transmission (API/JSON).
Alternative Methods
- Use
encryptFile(String, Path, Path)for automatic format selection (recommended) - Use
encryptFileCompact(String, Path, Path)for small files (below the server's configured compact limit)
Example
// Encrypt large video file EncryptResult result = sdk.encryptFileStream( "my-ml-kem-key", Path.of("movie.mp4"), Path.of("movie.jwet") );- Parameters:
kid- key identifier for encryption; must not benullinput- input file (any size, up to 100MB recommended); must not benulloutput- output file (.jwet recommended); must not benull- Returns:
- encryption result with metadata; never
null - Throws:
AnkaSecureSdkException- if operation fails- See Also:
-
decrypt
Decrypts a JWE (RFC 7516) token to recover the original plaintext.Accepts both serializations the SDK produces, detected from the content: Compact (§7.1, five dot-separated segments) and General JSON (§7.2, a JSON object, as
encrypt(String, byte[])returns for a composite KEM key).The JWE token is self-contained and includes all metadata required for decryption (algorithm, encrypted key, IV, ciphertext, authentication tag). The server resolves the correct decryption key based on the
kidheader in the JWE.This method is suitable for in-memory payloads up to ~100 MB. For larger files, use
decryptFileStream(Path, Path)to avoid loading the entire payload into memory.Example
// Decrypt a previously encrypted message String jweToken = "eyJhbGciOiJNTC1LRU0tNzY4IiwiZW5jIjoiQTI1NkdDTSIsImtpZCI6Im15LWtleSJ9..."; DecryptResult result = sdk.decrypt(jweToken); byte[] plaintext = result.getDecryptedData(); String message = new String(plaintext, StandardCharsets.UTF_8); System.out.println("Decrypted using key: " + result.getMeta().getKeyRequested()); System.out.println("Algorithm: " + result.getMeta().getAlgorithmUsed());Multi-key tokens: this form sends no
recipientKid, which the server reads as "the token names one key". For a JWE addressed to several keys it refuses the request with HTTP 400 namingrecipientKid; name the key withdecrypt(String, String).- Parameters:
ciphertextJwe- the Compact or General JSON JWE string to decrypt; must not benull- Returns:
- decryption result containing the plaintext bytes and operation metadata;
never
null - Throws:
AnkaSecureSdkException- if the JWE is neither a well-formed Compact nor a General JSON JWE (refused before any request is sent, withSdkErrorCode.MALFORMED_JOSE_INPUT), the decryption key is not accessible to the authenticated client, decryption fails (authentication tag mismatch), or the server returns an error. A header parameter name present both inprotectedand in a recipientheaderis refused with HTTP 400 whatever the two values (RFC 7516 §7.2.1: the header locations are disjoint).NullPointerException- ifciphertextJweisnull- See Also:
-
decrypt
public DecryptResult decrypt(String recipientKid, String ciphertextJwe) throws AnkaSecureSdkException Decrypts a JWE token string with the recipient the caller names.Same operation as
decrypt(String);recipientKidselects the recipient of a JWE addressed to several keys (RFC 7516 §7.2.1).Choosing the recipient
A JWE addressed to several keys (several recipients, each naming its key in its own header, and no
kidinprotected) is decrypted with exactly the recipientrecipientKidnames: one grant and one key-lifecycle decision are taken, on that key only, and no other recipient is ever tried. For a JWE that names one key (a single recipient, or a composite key's JWE)recipientKidmay benull; when present it must equal that key.Example
// A board-minutes JWE addressed to three custodians; this caller holds "custodian-b" DecryptResult result = sdk.decrypt("custodian-b", boardMinutesJwe); byte[] plaintext = result.getDecryptedData(); System.out.println("Decrypted with: " + result.getMeta().getKeyRequested() + " v" + result.getMeta().getMaterialVersion());- Parameters:
recipientKid- the key of the recipient to decrypt with;nullwhen the JWE names one key. Required when the JWE is addressed to several keysciphertextJwe- the Compact or General JSON JWE string to decrypt; must not benull- Returns:
- decryption result containing the plaintext bytes and the metadata of the key used;
never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingrecipientKidwhen it is absent for a JWE addressed to several keys or names no recipient of the JWE; HTTP 403 when the authenticated client holds no grant on that key; or when the operation otherwise fails. A header parameter name present both inprotectedand in a recipientheaderis refused with HTTP 400 whatever the two values (RFC 7516 §7.2.1: the header locations are disjoint).NullPointerException- ifciphertextJweisnullIllegalArgumentException- ifrecipientKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
decryptFileCompact
public DecryptResultMetadata decryptFileCompact(Path input, Path output) throws AnkaSecureSdkException Decrypts a file with forced compact format. Use when you need to decrypt a single-line JWE string. Fails if the input exceeds the server's configured compact limit (maxPlaintextBytes, default 4 MB).When to Use Compact Format
- API transmission: Decrypting JWE from JSON responses or HTTP headers
- Storage: Decrypting from single database field (text/varchar)
- Interoperability: JWE standard format (RFC 7516)
Input Format
Expects a single-line JWE, as written by
encryptFileCompact(String, Path, Path): RFC 7516 §7.1 Compact Serialization, or §7.2 General JSON Serialization for a composite KEM key. The form is detected from the content.Alternative Methods
- Use
decryptFile(Path, Path)for automatic format selection (recommended) - Use
decryptFileStream(Path, Path)for large files (above the server's configured compact limit)
Example
// Decrypt compact JWE file DecryptResultMetadata result = sdk.decryptFileCompact( Path.of("contract.jwe"), Path.of("contract.pdf") ); System.out.println("Decrypted using key: " + result.getKeyRequested());Multi-key tokens: this form sends no
recipientKid, which the server reads as "the token names one key". For a JWE addressed to several keys it refuses the request with HTTP 400 namingrecipientKid; name the key withdecryptFileCompact(String, Path, Path).- Parameters:
input- Compact or General JSON JWE file (up to the server's configured compact limit, default 4 MB); must not benulloutput- output file for decrypted plaintext; must not benull- Returns:
- decryption result metadata; never
null - Throws:
AnkaSecureSdkException- if the input is neither a well-formed Compact nor a General JSON JWE (refused before any request is sent, withSdkErrorCode.MALFORMED_JOSE_INPUT), exceeds the server's configured compact limit (HTTP 413), or the operation fails- See Also:
-
decryptFileCompact
public DecryptResultMetadata decryptFileCompact(String recipientKid, Path input, Path output) throws AnkaSecureSdkException Decrypts a Compact or General JSON JWE file with the recipient the caller names.Same operation as
decryptFileCompact(Path, Path);recipientKidselects the recipient of a JWE addressed to several keys.Choosing the recipient
A JWE addressed to several keys (several recipients, each naming its key in its own header, and no
kidinprotected) is decrypted with exactly the recipientrecipientKidnames: one grant and one key-lifecycle decision are taken, on that key only, and no other recipient is ever tried. For a JWE that names one key (a single recipient, or a composite key's JWE)recipientKidmay benull; when present it must equal that key.Example
DecryptResultMetadata meta = sdk.decryptFileCompact("custodian-b", Path.of("board-minutes.jwe"), Path.of("board-minutes.pdf"));- Parameters:
recipientKid- the key of the recipient to decrypt with;nullwhen the JWE names one key. Required when the JWE is addressed to several keysinput- Compact or General JSON JWE file (up to the server's configured compact limit); must not benulloutput- output file for the decrypted plaintext; must not benull- Returns:
- metadata of the key the JWE was decrypted with; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingrecipientKidwhen it is absent for a JWE addressed to several keys or names no recipient of the JWE; HTTP 403 when the authenticated client holds no grant on that key; or when the operation otherwise failsIllegalArgumentException- ifrecipientKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
decryptFile
Decrypts a file. Recommended for most use cases. Automatically selects the decryption path from the input envelope's actual format, not its size.This method inspects the input file's structure and routes accordingly:
- Compact JWE, or General JSON JWE for a composite KEM key (produced by
encryptFileCompact(String, Path, Path)orencryptFile(String, Path, Path)in compact mode): compact decrypt path. The two serializations are told apart by content (a JSON object versus five dot-separated segments), never by a flag. - Streaming JWET multipart artifact (produced by
encryptFileStream(String, Path, Path)): streaming decrypt path
Why Format, Not Size?
The input here is an envelope, not plaintext. A compact JWE is roughly twice the size of the plaintext it wraps, so its size may exceed the server's compact plaintext ceiling even though it is a compact envelope that must be decrypted via the compact path. Selecting by format guarantees that any file produced by
encryptFile/encryptFileCompactis always decryptable, and that a genuinely detached/streaming artifact is always decrypted via streaming.When to Use Explicit Formats
Use
decryptFileCompact(Path, Path)ordecryptFileStream(Path, Path)only when you specifically need to force a particular input format.Example
// Decrypt any file - works for both small and large files DecryptResultMetadata result = sdk.decryptFile( Path.of("data.jwe"), Path.of("data.bin") ); System.out.println("Decrypted using key: " + result.getKeyRequested());Multi-key tokens: this form sends no
recipientKid, which the server reads as "the token names one key". For a JWE addressed to several keys it refuses the request with HTTP 400 namingrecipientKid; name the key withdecryptFile(String, Path, Path).- Parameters:
input- input JWE file (any size): Compact, General JSON or streaming JWET; must not benulloutput- output file for decrypted plaintext; must not benull. By default fails ifoutputexists; callwithOverwrite()to overwrite.- Returns:
- decryption result metadata; never
null - Throws:
AnkaSecureSdkException- if the input is not a streaming JWET artifact (it does not begin with the multipart delimiter) and is not a well-formed Compact or General JSON JWE (refused before any request is sent, withSdkErrorCode.MALFORMED_JOSE_INPUT), or the operation fails. A General JSON input naming a header parameter both inprotectedand in a recipientheaderis refused with HTTP 400 (RFC 7516 §7.2.1: the header locations are disjoint); a streaming JWET artifact is refused asdecryptFileStream(Path, Path)describes.LocalFileException- if the input cannot be read or the output cannot be writtenDestinationExistsException- ifoutputalready exists and this instance usesOverwritePolicy.FAIL_IF_EXISTS(the default)- See Also:
- Compact JWE, or General JSON JWE for a composite KEM key (produced by
-
decryptFile
public DecryptResultMetadata decryptFile(String recipientKid, Path input, Path output) throws AnkaSecureSdkException Decrypts a file of any format with the recipient the caller names, selecting the path from the input's actual format exactly asdecryptFile(Path, Path)does.Choosing the recipient
A JWE addressed to several keys (several recipients, each naming its key in its own header, and no
kidinprotected) is decrypted with exactly the recipientrecipientKidnames: one grant and one key-lifecycle decision are taken, on that key only, and no other recipient is ever tried. For a JWE that names one key (a single recipient, or a composite key's JWE)recipientKidmay benull; when present it must equal that key.Example
DecryptResultMetadata meta = sdk.decryptFile("custodian-b", Path.of("board-minutes.jwe"), Path.of("board-minutes.pdf")); System.out.println("Decrypted with: " + meta.getKeyRequested());With PQC transport enabled, a streaming JWET artifact (recognised by its content, not its name) is processed over the TLS-only streaming route, as it was when it was encrypted; a compact envelope stays on the PQC-protected compact route.
- Parameters:
recipientKid- the key of the recipient to decrypt with;nullwhen the JWE names one key. Required when the JWE is addressed to several keysinput- input JWE file (any size): Compact, General JSON or streaming JWET; must not benulloutput- output file for the decrypted plaintext; must not benull- Returns:
- metadata of the key the JWE was decrypted with; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingrecipientKidwhen it is absent for a JWE addressed to several keys or names no recipient of the JWE; HTTP 403 when the authenticated client holds no grant on that key; or when the operation otherwise fails. A General JSON input naming a header parameter both inprotectedand in a recipientheaderis refused with HTTP 400 (RFC 7516 §7.2.1: the header locations are disjoint); a streaming JWET artifact is refused asdecryptFileStream(Path, Path)describes.IllegalArgumentException- ifrecipientKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
decryptFileStream
public DecryptResultMetadata decryptFileStream(Path input, Path output) throws AnkaSecureSdkException Decrypts a file with forced streaming format. Use for large files (100MB+), low-memory environments, or when binary input is acceptable.When to Use Streaming Format
- Large files: Files above the server's configured compact limit (required), optimal for 100MB+ (recommended)
- Memory constraints: Low-memory environments or embedded systems
- Binary output: When decrypting streaming JWE format (.jwet files)
- Progressive processing: Start processing before full download
Input Format
Binary streaming format (.jwet file) with multipart chunks. Typically created by
encryptFileStream(String, Path, Path).Alternative Methods
- Use
decryptFile(Path, Path)for automatic format selection (recommended) - Use
decryptFileCompact(Path, Path)for small files (below the server's configured compact limit)
Example
// Decrypt large video file DecryptResultMetadata result = sdk.decryptFileStream( Path.of("movie.jwet"), Path.of("movie.mp4") );Multi-key tokens: this form sends no
recipientKid, which the server reads as "the token names one key". For a JWE addressed to several keys it refuses the request with HTTP 400 namingrecipientKid; name the key withdecryptFileStream(String, Path, Path).- Parameters:
input- streaming JWE file (any size, up to 100MB recommended); must not benulloutput- output file for decrypted plaintext; must not benull- Returns:
- decryption result metadata; never
null - Throws:
AnkaSecureSdkException- if operation fails. The JWET header is refused with HTTP 422 and no payload byte, before any key is looked up, when it carries a root member besidesprotected,recipients,iv,ciphertext,tagand, on a composite key's header,anka_composite_mode(JWE_ROOT_MEMBER_FORBIDDEN; a JSONaadmember and a sharedunprotectedheader included) or a recipient member besidesheaderandencrypted_key(JWE_RECIPIENT_MEMBER_FORBIDDEN). A header parameter name present both inprotectedand in a recipient header (RFC 7516 §7.2.1) is refused with HTTP 422 for a single-recipient JWE and HTTP 400 for a composite JWE or one addressed to several keys.- See Also:
-
decryptFileStream
public DecryptResultMetadata decryptFileStream(String recipientKid, Path input, Path output) throws AnkaSecureSdkException Decrypts a streaming JWET file with the recipient the caller names; sent as therecipientKidquery parameter of/crypto/stream/decrypt.Choosing the recipient
A JWE addressed to several keys (several recipients, each naming its key in its own header, and no
kidinprotected) is decrypted with exactly the recipientrecipientKidnames: one grant and one key-lifecycle decision are taken, on that key only, and no other recipient is ever tried. For a JWE that names one key (a single recipient, or a composite key's JWE)recipientKidmay benull; when present it must equal that key.Example
DecryptResultMetadata meta = sdk.decryptFileStream("custodian-b", Path.of("archive.jwet"), Path.of("archive.tar"));- Parameters:
recipientKid- the key of the recipient to decrypt with;nullwhen the JWE names one key. Required when the JWE is addressed to several keysinput- streaming JWE file; must not benulloutput- output file for the decrypted plaintext; must not benull- Returns:
- metadata of the key the JWE was decrypted with; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingrecipientKidwhen it is absent for a JWE addressed to several keys or names no recipient of the JWE; HTTP 403 when the authenticated client holds no grant on that key; or when the operation otherwise fails. The JWET header is refused with HTTP 422 and no payload byte, before any key is looked up, when it carries a root member besidesprotected,recipients,iv,ciphertext,tagand, on a composite key's header,anka_composite_mode(JWE_ROOT_MEMBER_FORBIDDEN; a JSONaadmember and a sharedunprotectedheader included) or a recipient member besidesheaderandencrypted_key(JWE_RECIPIENT_MEMBER_FORBIDDEN). A header parameter name present both inprotectedand in a recipient header (RFC 7516 §7.2.1) is refused with HTTP 422 for a single-recipient JWE and HTTP 400 for a composite JWE or one addressed to several keys.IllegalArgumentException- ifrecipientKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
sign
Signs raw bytes using the key identified bykid.Creates a compact JWS (RFC 7515) containing the signature and all metadata needed for verification. The signing algorithm is determined by the key type: ML-DSA, ECDSA, or RSA-PSS.
This method is suitable for in-memory payloads up to ~100 MB. For larger files, use
signFileStream(String, Path, Path)to avoid loading the entire payload into memory.Example
byte[] document = Files.readAllBytes(Path.of("/contracts/agreement.pdf")); SignResult result = sdk.sign("legal-ml-dsa-key", document); // The JWS token contains the signature and can be verified later String jwsToken = result.getJwsToken(); // Verify later VerifySignatureResult verified = sdk.verifySignature(jwsToken); if (verified.isValid()) { System.out.println("Signature verified using key: " + verified.getSignatureResults().get(0).getKid()); }- Parameters:
kid- key identifier referencing a signing key stored in ANKASecure©; must not benulldata- the raw bytes to sign; must not benull- Returns:
- signature result containing the JWS token and operation metadata;
never
null - Throws:
AnkaSecureSdkException- if the key identified bykiddoes not exist, does not support signing, the authenticated client lacks permission, or the server returns an errorNullPointerException- ifkidordataisnull- See Also:
-
sign
public SignResult sign(String kid, byte[] data, JwsSerialization serialization) throws AnkaSecureSdkException Signs raw bytes, explicitly selecting the JWS serialization.Ergonomic overload of
sign(String, byte[]). PassJwsSerialization.COMPACTorJwsSerialization.JSONto request that representation; passingnullis equivalent tosign(String, byte[])(the server chooses the standards-correct representation). This axis never adds or drops a qualified timestamp.- Parameters:
kid- key identifier referencing a signing key; must not benulldata- the raw bytes to sign; must not benullserialization- requested serialization, ornullto let the server choose- Returns:
- signature result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 when COMPACT is requested but the deployment mandates a qualified timestampNullPointerException- ifkidordataisnull- See Also:
-
sign
public SignResult sign(String kid, byte[] data, JwsSerialization serialization, SignOptions options) throws AnkaSecureSdkException Signs raw bytes with an explicit serialization and signature options.SignOptions.validityDays()sets the signature's expiry (exp=iatplus that many days); an option left unset is not sent and the server's default applies (no expiry).SignResult signed = sdk.sign("my-ml-dsa-key", data, null, SignOptions.builder().validityDays(365).build());- Parameters:
kid- key identifier referencing a signing key; must not benulldata- the raw bytes to sign; must not benullserialization- requested serialization, ornullto let the server chooseoptions- the signature's options; must not benull(SignOptions.none()sets nothing)- Returns:
- signature result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 namingvalidityDayswhen it exceeds this deployment's maximum signature validityNullPointerException- ifkid,dataoroptionsisnull- See Also:
-
signFileCompact
public SignResult signFileCompact(String kid, Path input, Path output) throws AnkaSecureSdkException Signs a file with forced compact format. Use when you need a single-line string for API/JSON transmission. Fails if the input exceeds the server's configured compact limit (maxPlaintextBytes, default 4 MB).When to Use Compact Format
- API transmission: JSON responses, HTTP headers, query parameters
- Storage: Single database field (text/varchar)
- Interoperability: JWS standard format (RFC 7515)
Output Format
eyJhbGc...header...XVCJ9.eyJkYXRh...payload...9.dBjftJ...signature...
Single-line base64url string with embedded payload, suitable for text-based transmission.
Alternative Methods
- Use
signFile(String, Path, Path)for automatic format selection (recommended) - Use
signFileStream(String, Path, Path)for large files (above the server's configured compact limit)
Example
// Sign small document for API transmission SignResult result = sdk.signFileCompact( "my-ml-dsa-key", Path.of("contract.pdf"), Path.of("contract.jws") ); System.out.println("Algorithm: " + result.getAlgorithmUsed());- Parameters:
kid- key identifier for signing; must not benullinput- input file (up to the server's configured compact limit, default 4 MB); must not benulloutput- output file (.jws recommended); must not benull- Returns:
- signature result with metadata; never
null - Throws:
AnkaSecureSdkException- if the input exceeds the server's configured compact limit (HTTP 413) or operation fails- See Also:
-
signFileCompact
public SignResult signFileCompact(String kid, Path input, Path output, JwsSerialization serialization) throws AnkaSecureSdkException Signs a file (attached), explicitly selecting the JWS serialization.Ergonomic overload of
signFileCompact(String, Path, Path). Passingnulldefers to the server. When the deployment mandates a qualified timestamp, the written output is a JWS-JSON artifact carrying the JAdESsigTst(it is never collapsed to a compact string that would drop the stamp).- Parameters:
kid- key identifier for signing; must not benullinput- input file (max 5MB); must not benulloutput- output file; must not benullserialization- requested serialization, ornullto let the server choose- Returns:
- signature result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 when COMPACT is requested but the deployment mandates a qualified timestamp- See Also:
-
signFileCompact
public SignResult signFileCompact(String kid, Path input, Path output, JwsSerialization serialization, SignOptions options) throws AnkaSecureSdkException Signs a file (attached) with an explicit serialization and signature options.SignOptions.validityDays()sets the signature's expiry; an option left unset is not sent.- Parameters:
kid- key identifier for signing; must not benullinput- input file, up to the server's configured compact limit; must not benulloutput- output file; must not benullserialization- requested serialization, ornullto let the server chooseoptions- the signature's options; must not benull(SignOptions.none()sets nothing)- Returns:
- signature result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 namingvalidityDayswhen it exceeds this deployment's maximum signature validity- See Also:
-
signFile
Signs a file. Recommended for most use cases. Automatically selects optimal format based on file size (<5MB = compact, ≥5MB = streaming).This method automatically selects the optimal format:
- Files below the server's
maxPlaintextBytes: Compact JWS format (single-line string) - Files at or above that limit: Streaming JWS format (detached signature)
Why Use This Method?
You don't need to worry about file sizes or server limits. The threshold is discovered from the server (not hardcoded) and cached briefly; if a compact request is still rejected as too large (HTTP 413) the SDK transparently retries via streaming. With PQC transport enabled the SDK never moves to the TLS-only streaming route on its own: an oversized payload is refused with a hint to call the streaming operation, and only a 413 encrypted under the session key still falls back. This method handles everything automatically, ensuring your signing operation always succeeds regardless of file size.
When to Use Explicit Formats
Use
signFileCompact(String, Path, Path)orsignFileStream(String, Path, Path)only when you specifically need a particular output format (e.g., compact JWS for API transmission).This method takes no
SignOptions: it may choose the streaming route, whose request has novalidityDays. A caller that needs a signature validity usessignFileCompact(String, Path, Path, JwsSerialization, SignOptions)orsign(String, byte[], JwsSerialization, SignOptions).Example
// Sign any file - works for both small and large files SignResult result = sdk.signFile( "my-ml-dsa-key", Path.of("document.pdf"), Path.of("document.jws") ); System.out.println("Signed with: " + result.getAlgorithmUsed());- Parameters:
kid- key identifier for signing; must not benullinput- input file (any size); must not benulloutput- output file (.jws or .jwst); must not benull- Returns:
- signature result with metadata; never
nullBy default fails if
outputexists; callwithOverwrite()to overwrite. - Throws:
AnkaSecureSdkException- if operation failsLocalFileException- if the input cannot be read or the output cannot be writtenDestinationExistsException- ifoutputalready exists and this instance usesOverwritePolicy.FAIL_IF_EXISTS(the default)PqcTransportException- (STREAMING_NOT_CHOSEN) with PQC transport enabled, when the payload is at or above the advertised compact limit or a compact request is refused as too large in any response the session key did not authenticate: the streaming route is protected by TLS only, so the SDK does not choose it on its own. CallsignFileStream(String, Path, Path)explicitly to use it.- See Also:
- Files below the server's
-
signFileStream
Signs a file with forced streaming format. Use for large files (100MB+), low-memory environments, or when binary output is acceptable.When to Use Streaming Format
- Large files: Files above the server's configured compact limit (required), optimal for 100MB+ (recommended)
- Memory constraints: Low-memory environments or embedded systems
- Binary output: When detached signature format is acceptable
- Progressive processing: Start processing before full upload
Output Format
Detached JWS signature (.jwst file) where payload is stored separately. Suitable for large files where embedding the payload in the signature would be impractical.
Alternative Methods
- Use
signFile(String, Path, Path)for automatic format selection (recommended) - Use
signFileCompact(String, Path, Path)for small files (below the server's configured compact limit)
Example
// Sign large archive file SignResult result = sdk.signFileStream( "my-ml-dsa-key", Path.of("backup.tar.gz"), Path.of("backup.tar.gz.jwst") );- Parameters:
kid- key identifier for signing; must not benullinput- input file (any size, up to 100MB recommended); must not benulloutput- output file (.jwst recommended); must not benull- Returns:
- signature result with metadata; never
null - Throws:
AnkaSecureSdkException- if operation fails- See Also:
-
verifySignature
Verifies a JWS signature from a file, accepting either the compact form or the JWS-JSON form (serialization-agnostic).The file may contain an RFC 7515 §7.1 compact string OR an RFC 7515 §7.2 JWS-JSON object (which MAY carry a JAdES qualified timestamp in its unprotected header). The correct representation is detected automatically. Fails if the file is ≥5MB (server limit).
Alternative Methods
Note: No auto-detection method available because streaming verification requires separate data and signature file parameters.
- Use
verifySignature(Path)for compact or JWS-JSON files (<5MB) - Use
verifySignatureStream(Path, Path)for detached signatures (any size)
Example
// Verify a compact or JWS-JSON signature file VerifySignatureResult result = sdk.verifySignature( Path.of("document.jws") ); if (result.isValid()) { result.getSignatureResults().forEach(signer -> System.out.println("Signed by: " + signer.getKid() + " v" + signer.getMaterialVersion())); } // Informational: never affects isValid() if (result.getQualifiedTimestamp() != null) { System.out.println("Qualified timestamp trust: " + result.getQualifiedTimestamp().getTrustStatus()); }- Parameters:
jwsFile- compact or JWS-JSON signature file; must not benull- Returns:
- verification result; never
null - Throws:
AnkaSecureSdkException- if the input exceeds the server's configured compact limit (HTTP 413) or operation fails- See Also:
- Use
-
verifySignature
Verifies an attached JWS (RFC 7515) signature held in memory.The input may be the RFC 7515 §7.1 Compact Serialization or the §7.2 JWS JSON Serialization — which carries a JAdES qualified timestamp — detected from the content. The JWS is self-contained and includes all metadata required for verification (algorithm, signature, protected header). The server resolves the verification key from the
kidit carries.Example
String jwsToken = "eyJhbGciOiJNTC1EU0EtNjUiLCJraWQiOiJteS1rZXkifQ..."; VerifySignatureResult result = sdk.verifySignature(jwsToken); if (result.isValid()) { System.out.println("Signature verified"); result.getSignatureResults().forEach(signer -> System.out.println("Signed by key: " + signer.getKid() + " (" + signer.getAlgorithm() + ")")); } else { System.out.println("Signature verification failed"); }- Parameters:
jws- the Compact or JWS JSON Serialization string to verify; must not benull- Returns:
- verification result containing validity status and metadata; never
null - Throws:
AnkaSecureSdkException- if the JWS is not a well-formed Compact or JWS JSON Serialization (refused before any request is sent, withSdkErrorCode.MALFORMED_JOSE_INPUT), the verification key is not accessible, or the server returns an errorNullPointerException- ifjwsisnull- See Also:
-
verifySignatureStream
public VerifySignatureResult verifySignatureStream(Path dataFile, Path signatureFile) throws AnkaSecureSdkException Verifies a detached JWS signature with forced streaming format. Use for large files (100MB+), low-memory environments, or when binary output is acceptable.When to Use Streaming Format
- Large files: Files above the server's configured compact limit (required), optimal for 100MB+ (recommended)
- Memory constraints: Low-memory environments or embedded systems
- Binary output: When verifying detached JWS signature format (.jwst files)
- Progressive processing: Start verification before full upload
Input Format
Detached JWS signature (.jwst file) + separate data file. Typically created by
signFileStream(String, Path, Path).Alternative Methods
Note: No auto-detection method available because streaming verification requires separate data and signature file parameters.
- Use
verifySignature(Path)for compact JWS files (<5MB) - Use
verifySignatureStream(Path, Path)for detached signatures (any size)
Example
// Verify detached signature for large file VerifySignatureResult result = sdk.verifySignatureStream( Path.of("backup.tar.gz"), // Original data Path.of("backup.tar.gz.jwst") // Detached signature ); if (result.isValid()) { System.out.println("Signature valid!"); }- Parameters:
dataFile- original data file (any size, up to 100MB recommended); must not benullsignatureFile- detached JWS signature file; must not benull- Returns:
- verification result; never
null - Throws:
AnkaSecureSdkException- if operation fails- See Also:
-
listKeys
Lists ONE PAGE of the keys accessible to the authenticated client.Filters apply server-side BEFORE pagination, so the returned totals are filtered, tenant-scoped counts. Use
listAllKeys(KeyFilters)when the complete set is needed (client-side auto-pagination).Example
KeyPage page = sdk.listKeys(new KeyFilters(null, null, "ML-KEM", "active"), 0, 50); System.out.println("Page 1/" + page.totalPages() + " - " + page.totalElements() + " keys"); page.content().forEach(key -> System.out.println(key.getKid() + " (" + key.getAlg() + ")") );- Parameters:
filters- server-side filters;KeyFilters.none()for every key the tenant still holds, in any lifecycle state (destroyed keys are returned only when the status filter isdeleted_logical)page- zero-based page indexsize- page size (1..200; values above 200 are rejected by the server with 400)- Returns:
- the page of key metadata with totals; never
null - Throws:
AnkaSecureSdkException- if the server returns an error- See Also:
-
listAllKeys
Lists ALL keys matching the filters by auto-paginating through the server's paginated listing (the AWS-CLI pattern: the API pages, the client iterates).Bounded by the first page's
totalPagessnapshot with a defensive hard cap; exceeding it THROWSPaginationCeilingExceededExceptionrather than silently truncating. Offset-pagination drift between page fetches is accepted best-effort.Example
List<KeyMetadata> allKeys = sdk.listAllKeys(KeyFilters.none()); List<KeyMetadata> activeRsa = sdk.listAllKeys(new KeyFilters(null, null, "RSA", "active"));- Parameters:
filters- server-side filters;KeyFilters.none()for every key the tenant still holds, in any lifecycle state (destroyed keys are returned only when the status filter isdeleted_logical)- Returns:
- all matching key metadata; never
null, may be empty - Throws:
AnkaSecureSdkException- if the server returns an error- See Also:
-
getKeyMetadata
Retrieves metadata for a specific key.Example
KeyMetadata key = sdk.getKeyMetadata("my-ml-kem-768-key"); System.out.println("Key: " + key.getKid()); System.out.println("Algorithm: " + key.getAlg()); System.out.println("Status: " + key.getStatus()); System.out.println("Created: " + key.getCreatedAt());- Parameters:
kid- key identifier; must not benull- Returns:
- key metadata; never
null - Throws:
AnkaSecureSdkException- if the key does not exist, the authenticated client lacks permission, or the server returns an errorNullPointerException- ifkidisnull- See Also:
-
reencrypt
Re-encrypts data with a different key without decrypting to plaintext.Decrypts the JWE using the original key, then immediately re-encrypts with the new key. The plaintext never leaves the server, providing better security than decrypt + encrypt in the client.
This method is suitable for in-memory JWE tokens up to ~100 MB. For larger files, use
reencryptFileStream(String, String, Path, Path).Example
// Original encryption EncryptResult encrypted = sdk.encrypt("old-aes-key", data); String jweToken = encrypted.getJweToken(); // Migrate to post-quantum encryption ReencryptResult reencrypted = sdk.reencrypt("new-ml-kem-key", jweToken); System.out.println("Migrated from: " + reencrypted.getOldKeyAlgorithmUsed()); System.out.println("Migrated to: " + reencrypted.getNewKeyAlgorithmUsed());Multi-key tokens: this form sends no
sourceKid, which the server reads as "the token names one key". For a JWE addressed to several keys, or naming none, it refuses the request with HTTP 400 namingsourceKid; name the key withreencrypt(String, String, String).- Parameters:
newKid- identifier of the new encryption key; must not benulljweToken- the JWE token to re-encrypt, Compact or General JSON (detected from the content); must not benull- Returns:
- re-encryption result containing the new JWE (Compact when
newKidis a single-recipient key, General JSON when it is a composite KEM key) and migration metadata; nevernull - Throws:
AnkaSecureSdkException- if either key does not exist, the JWE is malformed, the authenticated client lacks permission, the JWE's one key andnewKidare of different classes (HTTP 400key-operation-incompatible: one symmetric, the other asymmetric; a composite key is asymmetric), or the server returns an error. A header parameter name present both inprotectedand in a recipientheaderis refused with HTTP 400 whatever the two values (RFC 7516 §7.2.1: the header locations are disjoint).NullPointerException- ifnewKidorjweTokenisnull- See Also:
-
reencrypt
public ReencryptResult reencrypt(String newKid, String sourceKid, String jweToken) throws AnkaSecureSdkException Re-encrypts a JWE tonewKid, replacing the recipient the caller names.Same operation as
reencrypt(String, String); the plaintext never leaves the server.Choosing the recipient to replace
For a JWE addressed to several keys,
sourceKidnames the ONE recipient whoseencrypted_keyis unwrapped;newKidtakes its position and every other recipient is kept, re-wrapped at its current PRIMARY.ReencryptResult.getRecipients()reports every recipient of the produced JWE. For a JWE that names one keysourceKidmay benull(when present it must equal that key); for a JWE that names none it is required and names the key the JWE was produced for.Example
// Rotate custodian A of a three-custodian JWE to the 2026 archive key ReencryptResult result = sdk.reencrypt("archive-2026", "custodian-a", boardMinutesJwe); for (ReencryptedRecipient r : result.getRecipients()) { System.out.println(r.getKid() + " (" + r.getAlgorithm() + ") v" + r.getMaterialVersion()); }- Parameters:
newKid- identifier of the key that takes the replaced recipient's position; must not benullsourceKid- the recipient this re-encryption replaces;nullwhen the JWE names one key. Required when the JWE is addressed to several keys or names nonejweToken- the JWE to re-encrypt, Compact or General JSON; must not benull- Returns:
- re-encryption result with the new JWE and every recipient of it; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no recipient of the JWE, HTTP 400 namingnewKidwhen it is one of the recipients the operation keeps, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric, the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWE addressed to several keys, the HTTP 422 refusals of a symmetric or composite recipient ornewKid(JOSE_SYMMETRIC_ACTOR,JWE_COMPOSITE_RECIPIENT) are decided before that HTTP 400. A header parameter name present both inprotectedand in a recipientheaderis refused with HTTP 400 whatever the two values (RFC 7516 §7.2.1: the header locations are disjoint).NullPointerException- ifnewKidorjweTokenisnullIllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
reencryptFileCompact
public ReencryptResult reencryptFileCompact(String newKid, Path input, Path output) throws AnkaSecureSdkException Re-encrypts a file with forced compact format. Use when you need a single-line string for API/JSON transmission. Fails if the input exceeds the server's configured compact limit (maxPlaintextBytes, default 4 MB).When to Use Compact Format
- API transmission: Re-encrypting for JSON responses or HTTP headers
- Storage: Re-encrypting for single database field (text/varchar)
- Interoperability: JWE standard format (RFC 7516)
Input and Output Format
The input may be RFC 7516 §7.1 Compact or §7.2 General JSON, detected from the content. The output is written in the serialization that carries every recipient of the new JWE: Compact when
newKidis a single-recipient key, General JSON when it is a composite KEM key (one recipient per component, which Compact Serialization cannot hold).Alternative Methods
- Use
reencryptFile(String, Path, Path)for automatic format selection (recommended) - Use
reencryptFileStream(String, String, Path, Path)for large files (above the server's configured compact limit)
Example
// Re-encrypt small file with new key ReencryptResult result = sdk.reencryptFileCompact( "new-ml-kem-key", Path.of("old-data.jwe"), Path.of("new-data.jwe") ); System.out.println("Migrated from: " + result.getOldKeyAlgorithmUsed()); System.out.println("Migrated to: " + result.getNewKeyAlgorithmUsed());Multi-key tokens: this form sends no
sourceKid, which the server reads as "the token names one key". For a JWE addressed to several keys, or naming none, it refuses the request with HTTP 400 namingsourceKid; name the key withreencryptFileCompact(String, String, Path, Path).- Parameters:
newKid- identifier of the new encryption key; must not benullinput- Compact or General JSON JWE file (up to the server's configured compact limit, default 4 MB); must not benulloutput- output file (.jwe recommended); receives the Compact JWE, or the General JSON JWE whennewKidis a composite KEM key; must not benull- Returns:
- re-encryption result with migration metadata; its
jweTokenis exactly what was written; nevernull - Throws:
AnkaSecureSdkException- if the input is neither a well-formed Compact nor a General JSON JWE (refused before any request is sent, withSdkErrorCode.MALFORMED_JOSE_INPUT), exceeds the server's configured compact limit (HTTP 413), is refused with HTTP 400key-operation-incompatiblewhen the JWE's one key andnewKidare of different classes (one symmetric, the other asymmetric; a composite key is asymmetric), or the operation fails- See Also:
-
reencryptFileCompact
public ReencryptResult reencryptFileCompact(String newKid, String sourceKid, Path input, Path output) throws AnkaSecureSdkException Re-encrypts a Compact or General JSON JWE file tonewKid, replacing the recipient the caller names.Choosing the recipient to replace
For a JWE addressed to several keys,
sourceKidnames the ONE recipient whoseencrypted_keyis unwrapped;newKidtakes its position and every other recipient is kept, re-wrapped at its current PRIMARY.ReencryptResult.getRecipients()reports every recipient of the produced JWE. For a JWE that names one keysourceKidmay benull(when present it must equal that key); for a JWE that names none it is required and names the key the JWE was produced for.Example
ReencryptResult result = sdk.reencryptFileCompact("archive-2026", "custodian-a", Path.of("board-minutes.jwe"), Path.of("board-minutes.rotated.jwe"));- Parameters:
newKid- identifier of the key that takes the replaced recipient's position; must not benullsourceKid- the recipient this re-encryption replaces;nullwhen the JWE names one key. Required when the JWE is addressed to several keys or names noneinput- Compact or General JSON JWE file; must not benulloutput- output file receiving the re-encrypted JWE; must not benull- Returns:
- re-encryption result with every recipient of the produced JWE; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no recipient of the JWE, HTTP 400 namingnewKidwhen it is one of the recipients the operation keeps, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric, the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWE addressed to several keys, the HTTP 422 refusals of a symmetric or composite recipient ornewKid(JOSE_SYMMETRIC_ACTOR,JWE_COMPOSITE_RECIPIENT) are decided before that HTTP 400IllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
reencryptFile
public ReencryptResult reencryptFile(String newKid, Path input, Path output) throws AnkaSecureSdkException Re-encrypts a file. Recommended for most use cases. Automatically selects the re-encryption path from the input envelope's actual format, not its size.This method inspects the input file's structure and routes accordingly:
- Compact JWE, or General JSON JWE for a composite KEM key (produced by
encryptFileCompact(String, Path, Path)orencryptFile(String, Path, Path)in compact mode): compact re-encrypt path, whose output follows the same rule fornewKid(Compact for a single-recipient key, General JSON for a composite KEM key) - Streaming JWET multipart artifact (produced by
encryptFileStream(String, Path, Path)): streaming re-encrypt path
Why Format, Not Size?
The input here is an envelope, not plaintext. A compact JWE is roughly twice the size of the plaintext it wraps, so its size may exceed the server's compact plaintext ceiling even though it is a compact envelope that must be re-encrypted via the compact path. Selecting by format guarantees that any file produced by
encryptFile/encryptFileCompactis always re-encryptable, and that a genuinely detached/streaming artifact is always re-encrypted via streaming.When to Use Explicit Formats
Use
reencryptFileCompact(String, Path, Path)orreencryptFileStream(String, String, Path, Path)only when you specifically need to force a particular format.Example
// Re-encrypt any file - works for both small and large files ReencryptResult result = sdk.reencryptFile( "new-ml-kem-key", Path.of("old-data.jwe"), Path.of("new-data.jwe") ); System.out.println("Migrated from: " + result.getOldKeyAlgorithmUsed()); System.out.println("Migrated to: " + result.getNewKeyAlgorithmUsed());Multi-key tokens: this form sends no
sourceKid, which the server reads as "the token names one key". For a JWE addressed to several keys, or naming none, it refuses the request with HTTP 400 namingsourceKid; name the key withreencryptFile(String, String, Path, Path).- Parameters:
newKid- identifier of the new encryption key; must not benullinput- input JWE file (any size): Compact, General JSON or streaming JWET; must not benulloutput- output file (.jwe or .jwet); must not benull. By default fails ifoutputexists; callwithOverwrite()to overwrite.- Returns:
- re-encryption result with migration metadata; never
null - Throws:
AnkaSecureSdkException- if the input is not a streaming JWET artifact (it does not begin with the multipart delimiter) and is not a well-formed Compact or General JSON JWE (refused before any request is sent, withSdkErrorCode.MALFORMED_JOSE_INPUT), is refused with HTTP 400key-operation-incompatiblewhen the JWE's one key andnewKidare of different classes (one symmetric, the other asymmetric; a composite key is asymmetric), or the operation fails. A General JSON input naming a header parameter both inprotectedand in a recipientheaderis refused with HTTP 400 (RFC 7516 §7.2.1: the header locations are disjoint); a streaming JWET artifact is refused asreencryptFileStream(String, String, Path, Path)describes.LocalFileException- if the input cannot be read or the output cannot be writtenDestinationExistsException- ifoutputalready exists and this instance usesOverwritePolicy.FAIL_IF_EXISTS(the default)- See Also:
- Compact JWE, or General JSON JWE for a composite KEM key (produced by
-
reencryptFile
public ReencryptResult reencryptFile(String newKid, String sourceKid, Path input, Path output) throws AnkaSecureSdkException Re-encrypts a file of any format tonewKid, replacing the recipient the caller names, and selecting the path from the input's actual format exactly asreencryptFile(String, Path, Path)does.Choosing the recipient to replace
For a JWE addressed to several keys,
sourceKidnames the ONE recipient whoseencrypted_keyis unwrapped;newKidtakes its position and every other recipient is kept, re-wrapped at its current PRIMARY. For a JWE that names one keysourceKidmay benull(when present it must equal that key); for a JWE that names none it is required and names the key the JWE was produced for.A Compact or General JSON input takes the compact path, and
ReencryptResult.getRecipients()reports every recipient of the produced JWE. A streaming JWET input takesreencryptFileStream(String, String, Path, Path), whose response carries no per-recipient detail:getRecipients()isnullthere.Example
ReencryptResult result = sdk.reencryptFile("archive-2026", "custodian-a", Path.of("board-minutes.jwe"), Path.of("board-minutes.rotated.jwe"));With PQC transport enabled, a streaming JWET artifact (recognised by its content, not its name) is processed over the TLS-only streaming route, as it was when it was encrypted; a compact envelope stays on the PQC-protected compact route.
- Parameters:
newKid- identifier of the key that takes the replaced recipient's position; must not benullsourceKid- the recipient this re-encryption replaces;nullwhen the JWE names one key. Required when the JWE is addressed to several keys or names noneinput- input JWE file (any size): Compact, General JSON or streaming JWET; must not benulloutput- output file; must not benull- Returns:
- re-encryption result; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no recipient of the JWE, HTTP 400 namingnewKidwhen it is one of the recipients the operation keeps, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric, the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWE addressed to several keys, the HTTP 422 refusals of a symmetric or composite recipient ornewKid(JOSE_SYMMETRIC_ACTOR,JWE_COMPOSITE_RECIPIENT) are decided before that HTTP 400. A General JSON input naming a header parameter both inprotectedand in a recipientheaderis refused with HTTP 400 (RFC 7516 §7.2.1: the header locations are disjoint); a streaming JWET artifact is refused asreencryptFileStream(String, String, Path, Path)describes.IllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
reencryptFileStream
public ReencryptResult reencryptFileStream(String newKid, String sourceKid, Path input, Path output) throws AnkaSecureSdkException Re-encrypts a file with forced streaming format. Use for large files (100MB+), low-memory environments, or when binary output is acceptable.When to Use Streaming Format
- Large files: Files above the server's configured compact limit (required), optimal for 100MB+ (recommended)
- Memory constraints: Low-memory environments or embedded systems
- Binary output: When re-encrypting to streaming JWE format (.jwet files)
- Progressive processing: Start processing before full upload
- Key rotation: Migrating archived data to new encryption keys
Alternative Methods
- Use
reencryptFile(String, Path, Path)for automatic format selection (recommended) - Use
reencryptFileCompact(String, Path, Path)for small files (below the server's configured compact limit)
Example
// Re-encrypt large file with new key ReencryptResult result = sdk.reencryptFileStream( "new-ml-kem-key", null, // the JWE names one key Path.of("backup.jwet"), Path.of("backup-new.jwet") );- Parameters:
newKid- identifier of the new encryption key; must not benullsourceKid- the recipient this re-encryption replaces;nullwhen the JWE names one key. Required when the JWE is addressed to several keys or names none; sent as thesourceKidquery parameterinput- streaming JWE file (any size, up to 100MB recommended); must not benulloutput- output file (.jwet recommended); must not benull- Returns:
- re-encryption result with migration metadata; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no recipient of the JWE, HTTP 400 namingnewKidwhen it is one of the recipients the operation keeps, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric, the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWE addressed to several keys, the HTTP 422 refusals of a symmetric or composite recipient ornewKid(JOSE_SYMMETRIC_ACTOR,JWE_COMPOSITE_RECIPIENT) are decided before that HTTP 400. The JWET header is refused with HTTP 422 and no payload byte, before any key is looked up, when it carries a root member besidesprotected,recipients,iv,ciphertext,tagand, on a composite key's header,anka_composite_mode(JWE_ROOT_MEMBER_FORBIDDEN; a JSONaadmember and a sharedunprotectedheader included) or a recipient member besidesheaderandencrypted_key(JWE_RECIPIENT_MEMBER_FORBIDDEN). A header parameter name present both inprotectedand in a recipient header (RFC 7516 §7.2.1) is refused with HTTP 422 for a single-recipient JWE and HTTP 400 for a composite JWE or one addressed to several keys.IllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
resign
Re-signs data with a different key without verifying the original signature.Strips the old signature and creates a new JWS with the new signing key. This is useful for key rotation or migrating signatures to post-quantum algorithms.
This method is suitable for in-memory JWS tokens up to ~100 MB. For larger files, use
resignFileStream(Path, String, Path, Path).Example
// Original signature SignResult signed = sdk.sign("old-ecdsa-key", document); String jwsToken = signed.getJwsToken(); // Migrate to post-quantum signature ResignResult resigned = sdk.resign("new-ml-dsa-key", jwsToken); System.out.println("Migrated from: " + resigned.getOldKeyAlgorithmUsed()); System.out.println("Migrated to: " + resigned.getNewKeyAlgorithmUsed());Multi-key tokens: this form sends no
sourceKid, which the server reads as "the token names one key". For a JWS signed by several keys, or naming none, it refuses the request with HTTP 400 namingsourceKid; name the key withresign(String, String, String).- Parameters:
newKid- identifier of the new signing key; must not benulljws- the JWS token to re-sign; must not benull- Returns:
- re-sign result containing new JWS and migration metadata;
never
null - Throws:
AnkaSecureSdkException- if either key does not exist, the JWS is malformed, the authenticated client lacks permission, the JWS's one key andnewKidare of different classes (HTTP 400key-operation-incompatible: one symmetric (HMAC), the other asymmetric; a composite key is asymmetric), or the server returns an errorNullPointerException- ifnewKidorjwsisnull- See Also:
-
resign
public ResignResult resign(String newKid, String sourceKid, String jws) throws AnkaSecureSdkException Re-signs a JWS withnewKid, replacing the signature of the signer the caller names.Choosing the signature to replace
For a JWS signed by several keys,
sourceKidnames the ONE signer whose signature is replaced; every signature of the input is verified under its own key first, andResignResult.getSignatureResults()reports each of them. When the protected header names akid,sourceKidmay benull(when present it must equal it); when the header names none it is required and names the key that signed.Example
// Replace the 2019 legal signature of a two-signer contract JWS ResignResult result = sdk.resign("legal-mldsa-2026", "legal-rsa-2019", contractJws); result.getSignatureResults().forEach(s -> System.out.println("input signer " + s.getKid() + " v" + s.getMaterialVersion()));- Parameters:
newKid- identifier of the new signing key; must not benullsourceKid- the signer whose signature is replaced;nullwhen the protected header names one key. Required for a JWS signed by several keys or naming nonejws- the JWS to re-sign (Compact or JWS JSON); must not benull- Returns:
- re-sign result with the new JWS and every signature of the input; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no signer, HTTP 400 when any input signature does not verify, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWS signed by several keys, the HTTP 422JOSE_SYMMETRIC_ACTORrefusal of a symmetric signer ornewKidis decided before that HTTP 400NullPointerException- ifnewKidorjwsisnullIllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
resign
public ResignResult resign(String newKid, String jws, JwsSerialization serialization) throws AnkaSecureSdkException Re-signs a JWS, explicitly selecting the JWS serialization.Ergonomic overload of
resign(String, String). Passingnulldefers to the server. The input JWS may be compact or JWS-JSON.A literal
nullthird argument,resign(newKid, jws, null), also matchesresign(String, String, String)(whose second argument issourceKid), so the compiler refuses the call as ambiguous. Pass a typed(JwsSerialization) null, or callresign(String, String), which is the same request.Multi-key tokens: this form sends no
sourceKid, which the server reads as "the token names one key". For a JWS signed by several keys, or naming none, it refuses the request with HTTP 400 namingsourceKid; name the key withresign(String, String, String, JwsSerialization).- Parameters:
newKid- identifier of the new signing key; must not benulljws- the JWS to re-sign (compact or JWS-JSON); must not benullserialization- requested serialization, ornullto let the server choose- Returns:
- re-sign result with migration metadata; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 when COMPACT is requested but the deployment mandates a qualified timestamp, and HTTP 400key-operation-incompatiblewhen the JWS's one key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric)NullPointerException- ifnewKidorjwsisnull- See Also:
-
resign
public ResignResult resign(String newKid, String sourceKid, String jws, JwsSerialization serialization) throws AnkaSecureSdkException Re-signs a JWS withnewKid, replacing the signature of the signer the caller names and selecting the JWS serialization.Choosing the signature to replace
For a JWS signed by several keys,
sourceKidnames the ONE signer whose signature is replaced; every signature of the input is verified under its own key first, andResignResult.getSignatureResults()reports each of them. When the protected header names akid,sourceKidmay benull(when present it must equal it); when the header names none it is required and names the key that signed.Example
ResignResult result = sdk.resign("legal-mldsa-2026", "legal-rsa-2019", contractJws, JwsSerialization.JSON);- Parameters:
newKid- identifier of the new signing key; must not benullsourceKid- the signer whose signature is replaced;nullwhen the protected header names one key. Required for a JWS signed by several keys or naming nonejws- the JWS to re-sign (Compact or JWS JSON); must not benullserialization- requested serialization, ornullto let the server choose- Returns:
- re-sign result with the new JWS and every signature of the input; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no signer, HTTP 400 when any input signature does not verify, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWS signed by several keys, the HTTP 422JOSE_SYMMETRIC_ACTORrefusal of a symmetric signer ornewKidis decided before that HTTP 400NullPointerException- ifnewKidorjwsisnullIllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
resignFileCompact
public ResignResult resignFileCompact(String newKid, Path input, Path output) throws AnkaSecureSdkException Re-signs a compact JWS file with forced compact format. Use when you need a single-line string for API/JSON transmission. Fails if the input exceeds the server's configured compact limit (maxPlaintextBytes, default 4 MB).When to Use Compact Format
- API transmission: Re-signing for JSON responses or HTTP headers
- Storage: Re-signing for single database field (text/varchar)
- Interoperability: JWS standard format (RFC 7515)
Alternative Methods
Note: No auto-detection method available because streaming re-signing requires separate data and signature file parameters.
- Use
resignFileCompact(String, Path, Path)for compact JWS files (below the server's configured compact limit) - Use
resignFileStream(Path, String, Path, Path)for detached signatures (any size)
Example
// Re-sign compact JWS with new key ResignResult result = sdk.resignFileCompact( "new-ml-dsa-key", Path.of("old-signature.jws"), Path.of("new-signature.jws") ); System.out.println("Migrated from: " + result.getOldKeyAlgorithmUsed()); System.out.println("Migrated to: " + result.getNewKeyAlgorithmUsed());Multi-key tokens: this form sends no
sourceKid, which the server reads as "the token names one key". For a JWS signed by several keys, or naming none, it refuses the request with HTTP 400 namingsourceKid; name the key withresignFileCompact(String, String, Path, Path).- Parameters:
newKid- identifier of the new signing key; must not benullinput- compact JWS file (up to the server's configured compact limit, default 4 MB); must not benulloutput- output file (.jws recommended); must not benull- Returns:
- re-sign result with migration metadata; never
null - Throws:
AnkaSecureSdkException- with HTTP 413 when the input exceeds the server's configured compact limit, HTTP 400key-operation-incompatiblewhen the JWS's one key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric), or when the operation otherwise fails- See Also:
-
resignFileCompact
public ResignResult resignFileCompact(String newKid, String sourceKid, Path input, Path output) throws AnkaSecureSdkException Re-signs a JWS file withnewKid, replacing the signature of the signer the caller names.Choosing the signature to replace
For a JWS signed by several keys,
sourceKidnames the ONE signer whose signature is replaced; every signature of the input is verified under its own key first, andResignResult.getSignatureResults()reports each of them. When the protected header names akid,sourceKidmay benull(when present it must equal it); when the header names none it is required and names the key that signed.Example
ResignResult result = sdk.resignFileCompact("legal-mldsa-2026", "legal-rsa-2019", Path.of("contract.jws"), Path.of("contract.resigned.jws"));- Parameters:
newKid- identifier of the new signing key; must not benullsourceKid- the signer whose signature is replaced;nullwhen the protected header names one key. Required for a JWS signed by several keys or naming noneinput- input JWS file (Compact or JWS JSON); must not benulloutput- output file; must not benull- Returns:
- re-sign result with every signature of the input; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no signer, HTTP 400 when any input signature does not verify, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWS signed by several keys, the HTTP 422JOSE_SYMMETRIC_ACTORrefusal of a symmetric signer ornewKidis decided before that HTTP 400IllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
resignFileCompact
public ResignResult resignFileCompact(String newKid, Path input, Path output, JwsSerialization serialization) throws AnkaSecureSdkException Re-signs a JWS file (attached), explicitly selecting the JWS serialization.Ergonomic overload of
resignFileCompact(String, Path, Path). Passingnulldefers to the server. When the deployment mandates a qualified timestamp, the written output is a JWS-JSON artifact carrying the JAdESsigTst.Multi-key tokens: this form sends no
sourceKid, which the server reads as "the token names one key". For a JWS signed by several keys, or naming none, it refuses the request with HTTP 400 namingsourceKid; name the key withresignFileCompact(String, String, Path, Path, JwsSerialization).- Parameters:
newKid- identifier of the new signing key; must not benullinput- input JWS file (compact or JWS-JSON, max 5MB); must not benulloutput- output file; must not benullserialization- requested serialization, ornullto let the server choose- Returns:
- re-sign result with migration metadata; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 when COMPACT is requested but the deployment mandates a qualified timestamp, and HTTP 400key-operation-incompatiblewhen the JWS's one key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric)- See Also:
-
resignFileCompact
public ResignResult resignFileCompact(String newKid, String sourceKid, Path input, Path output, JwsSerialization serialization) throws AnkaSecureSdkException Re-signs a JWS file withnewKid, replacing the signature of the signer the caller names and selecting the JWS serialization.Choosing the signature to replace
For a JWS signed by several keys,
sourceKidnames the ONE signer whose signature is replaced; every signature of the input is verified under its own key first, andResignResult.getSignatureResults()reports each of them. When the protected header names akid,sourceKidmay benull(when present it must equal it); when the header names none it is required and names the key that signed.Example
ResignResult result = sdk.resignFileCompact("legal-mldsa-2026", "legal-rsa-2019", Path.of("contract.jws"), Path.of("contract.resigned.jws"), JwsSerialization.JSON);- Parameters:
newKid- identifier of the new signing key; must not benullsourceKid- the signer whose signature is replaced;nullwhen the protected header names one key. Required for a JWS signed by several keys or naming noneinput- input JWS file (Compact or JWS JSON); must not benulloutput- output file; must not benullserialization- requested serialization, ornullto let the server choose- Returns:
- re-sign result with every signature of the input; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no signer, HTTP 400 when any input signature does not verify, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWS signed by several keys, the HTTP 422JOSE_SYMMETRIC_ACTORrefusal of a symmetric signer ornewKidis decided before that HTTP 400IllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
resignFileStream
public ResignResult resignFileStream(Path oldJwsHeader, String newKid, Path input, Path output) throws AnkaSecureSdkException Re-signs a detached JWS signature with forced streaming format. Use for large files (100MB+), low-memory environments, or when binary output is acceptable.When to Use Streaming Format
- Large files: Files above the server's configured compact limit (required), optimal for 100MB+ (recommended)
- Memory constraints: Low-memory environments or embedded systems
- Binary output: When re-signing detached JWS signature format (.jwst files)
- Progressive processing: Start processing before full upload
- Key rotation: Migrating archived signatures to new signing keys
Input Format
Detached JWS signature (.jwst file) + separate data file. Typically created by
signFileStream(String, Path, Path).Alternative Methods
Note: No auto-detection method available because streaming re-signing requires separate data and signature file parameters.
- Use
resignFileCompact(String, Path, Path)for compact JWS files (below the server's configured compact limit) - Use
resignFileStream(Path, String, Path, Path)for detached signatures (any size)
Example
// Re-sign detached signature for large file ResignResult result = sdk.resignFileStream( Path.of("backup.tar.gz.jwst"), // Old JWS header "new-ml-dsa-key", Path.of("backup.tar.gz"), // Original data Path.of("backup-new.tar.gz.jwst") // New signature );Multi-key tokens: this form sends no
sourceKid, which the server reads as "the token names one key". For a JWS signed by several keys, or naming none, it refuses the request with HTTP 400 namingsourceKid; name the key withresignFileStream(Path, String, String, Path, Path).- Parameters:
oldJwsHeader- old JWS header file (for metadata extraction); must not benullnewKid- identifier of the new signing key; must not benullinput- original data file (any size, up to 100MB recommended); must not benulloutput- output file (.jwst recommended); must not benull- Returns:
- re-sign result with migration metadata; never
null - Throws:
AnkaSecureSdkException- with HTTP 400key-operation-incompatiblewhen the JWS's one key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric), or when the operation otherwise fails- See Also:
-
resignFileStream
public ResignResult resignFileStream(Path oldJwsHeader, String newKid, String sourceKid, Path input, Path output) throws AnkaSecureSdkException Re-signs a detached JWS in streaming mode, naming the signer whose signature is replaced; sent as thesourceKidmember of the/crypto/stream/resignmetadata part.Choosing the signature to replace
For a JWS signed by several keys,
sourceKidnames the ONE signer whose signature is replaced; every signature of the input is verified under its own key first. When the protected header names akid,sourceKidmay benull(when present it must equal it); when the header names none it is required and names the key that signed.The streaming response is the new detached JWS and an end-of-stream verdict; it carries no per-signature detail, so
ResignResult.getSignatureResults()isnullon this path (useresignFileCompact(String, String, Path, Path)to read every input signer). The new signature is written only when the verdict is VALID and the result crosses keys.Example
ResignResult result = sdk.resignFileStream(Path.of("backup.tar.gz.jwst"), "archive-mldsa-2026", null, Path.of("backup.tar.gz"), Path.of("backup-new.tar.gz.jwst"));- Parameters:
oldJwsHeader- the detached JWS being replaced; must not benullnewKid- identifier of the new signing key; must not benullsourceKid- the signer whose signature is replaced;nullwhen the protected header names one key. Required for a JWS signed by several keys or naming noneinput- original data file; must not benulloutput- output file for the new detached JWS; must not benull- Returns:
- re-sign result naming the replaced and the replacing key (
getSignatureResults()isnullon this path); nevernull - Throws:
AnkaSecureSdkException- with HTTP 400 namingsourceKidwhen it is absent where required or names no signer, HTTP 400 when any input signature does not verify, HTTP 400key-operation-incompatiblewhen the source key andnewKidare of different classes (one symmetric (HMAC), the other asymmetric; a composite key is asymmetric), HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when the operation otherwise fails. For a JWS signed by several keys, the HTTP 422JOSE_SYMMETRIC_ACTORrefusal of a symmetric signer ornewKidis decided before that HTTP 400StreamIntegrityException- if the end-of-stream verdict is INVALID or absent (no output is written)IllegalArgumentException- ifsourceKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
resignFileStream
public ResignResult resignFileStream(Path oldJwsHeader, String newKid, String sourceKid, Path input, Path output, SignOptions options) throws AnkaSecureSdkException Re-signs a file in streaming mode with options for the new signature.SignOptions.validityDays()sets the new signature's expiry, whatever the source's kind; an option left unset is not sent.- Parameters:
oldJwsHeader- the detached JWS (JWS JSON) whose signature is replaced; must not benullnewKid- the key that signs the new signature; must not benullsourceKid- the signer whose signature is replaced, ornullwhen the header names one keyinput- the detached payload; must not benulloutput- destination of the new detached JWS; must not benulloptions- the new signature's options; must not benull(SignOptions.none()sets nothing)- Returns:
- re-sign result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 namingvalidityDayswhen it exceeds this deployment's maximum signature validity- See Also:
-
signThenEncrypt
public SignEncryptResult signThenEncrypt(String signKid, String encryptKid, byte[] data) throws AnkaSecureSdkException Signs then encrypts data in a single operation (nested JWE containing JWS).Creates a JWS signature, then encrypts the entire JWS as a JWE. This provides both authenticity (signature) and confidentiality (encryption). The recipient must decrypt first, then verify the signature.
This method is suitable for in-memory payloads up to ~100 MB. For larger files, use
signThenEncryptFileCompact(String, String, Path, Path).Example
byte[] sensitiveDoc = Files.readAllBytes(Path.of("/contracts/agreement.pdf")); SignEncryptResult result = sdk.signThenEncrypt( "my-ml-dsa-key", // signing key "my-ml-kem-key", // encryption key sensitiveDoc ); // Later: decrypt then verify DecryptVerifyResult verified = sdk.decryptThenVerify(result.getJweToken()); if (verified.isSignatureValid()) { System.out.println("Signature valid, data authentic"); }- Parameters:
signKid- identifier of the signing key; must not benullencryptKid- identifier of the encryption key; must not benulldata- the raw bytes to sign and encrypt; must not benull- Returns:
- result containing nested JWE token and operation metadata;
never
null - Throws:
AnkaSecureSdkException- if either key does not exist, the authenticated client lacks permission, or the server returns an errorNullPointerException- if any parameter isnull- See Also:
-
signThenEncrypt
public SignEncryptResult signThenEncrypt(String signKid, String encryptKid, byte[] data, JwsSerialization serialization) throws AnkaSecureSdkException Signs then encrypts, explicitly selecting the inner-JWS serialization.Ergonomic overload of
signThenEncrypt(String, String, byte[]). Passingnulldefers to the server. Governs only the inner JWS representation and never changes the outer JWE.- Parameters:
signKid- private key identifier for signing; must not benullencryptKid- public key identifier for encryption; must not benulldata- plaintext bytes to sign and encrypt; must not benullserialization- requested inner-JWS serialization, ornullto defer- Returns:
- combined sign-encrypt result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 (before any signing or encryption) when COMPACT is requested but the deployment mandates a qualified timestampNullPointerException- if any ofsignKid,encryptKid, ordataisnull- See Also:
-
signThenEncrypt
public SignEncryptResult signThenEncrypt(String signKid, String encryptKid, byte[] data, JwsSerialization serialization, SignOptions options) throws AnkaSecureSdkException Signs then encrypts data with an explicit inner serialization and options for the inner signature.SignOptions.validityDays()sets the inner signature's expiry; an option left unset is not sent.- Parameters:
signKid- identifier of the signing key; must not benullencryptKid- identifier of the encryption key; must not benulldata- the raw bytes to sign and encrypt; must not benullserialization- requested inner-JWS serialization, ornullto let the server chooseoptions- the inner signature's options; must not benull- Returns:
- nested JWE(JWS) result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 namingvalidityDayswhen it exceeds this deployment's maximum signature validity- See Also:
-
decryptThenVerify
Decrypts a JWE then verifies the inner JWS signature.Reverses
signThenEncrypt(String, String, byte[])by decrypting the outer JWE, then verifying the inner JWS signature. Both operations must succeed for the overall operation to succeed.Example
// Received encrypted and signed document String jweToken = "eyJhbGciOiJNTC1LRU0tNzY4IiwiZW5jIjoiQTI1NkdDTSJ9..."; DecryptVerifyResult result = sdk.decryptThenVerify(jweToken); if (result.isSignatureValid()) { byte[] authenticData = result.getDecryptedData(); System.out.println("Decrypted and verified successfully"); } else { System.out.println("Signature verification failed"); }Multi-key tokens: this form sends no
recipientKid, which the server reads as "the token names one key". For a JWE addressed to several keys it refuses the request with HTTP 400 namingrecipientKid; name the key withdecryptThenVerify(String, String).- Parameters:
jweToken- the nested JWE token to decrypt and verify, Compact or General JSON (as returned for a composite KEM encryption key; detected from the content); must not benull- Returns:
- result containing decrypted data and verification status;
never
null - Throws:
AnkaSecureSdkException- if the JWE is malformed, decryption fails, the JWS is malformed, or the server returns an error. A header parameter name present both inprotectedand in a recipientheaderis refused with HTTP 400 whatever the two values (RFC 7516 §7.2.1: the header locations are disjoint).NullPointerException- ifjweTokenisnull- See Also:
-
decryptThenVerify
public DecryptVerifyResult decryptThenVerify(String recipientKid, String jweToken) throws AnkaSecureSdkException Decrypts a nested JWE(JWS) token with the recipient the caller names, then verifies every signature of the inner JWS.Choosing the recipient and reading every signer
recipientKidnames the recipient of the outer JWE to decrypt with, exactly as fordecrypt(String, String); it must be none of the inner JWS's signers. Every signature of the inner JWS is verified under its own key, andDecryptVerifyResult.getSignatureResults()reports each of them in token order.Example
DecryptVerifyResult result = sdk.decryptThenVerify("custodian-b", signedMinutesJwe); for (SignatureResult signer : result.getSignatureResults()) { System.out.println(signer.getKid() + " " + signer.getAlgorithm() + " v" + signer.getMaterialVersion() + " verified=" + signer.getVerified()); }- Parameters:
recipientKid- the key of the recipient to decrypt with;nullwhen the JWE names one key. Required when the JWE is addressed to several keysjweToken- the nested JWE token, Compact or General JSON; must not benull- Returns:
- result with the plaintext, the decryption key's metadata and one entry per inner
signature; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingrecipientKidwhen it is absent for an outer JWE addressed to several keys or names no recipient, HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when decryption or verification otherwise fails. A header parameter name present both inprotectedand in a recipientheaderis refused with HTTP 400 whatever the two values (RFC 7516 §7.2.1: the header locations are disjoint).NullPointerException- ifjweTokenisnullIllegalArgumentException- ifrecipientKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
signThenEncryptFileCompact
public SignEncryptResult signThenEncryptFileCompact(String signKid, String encryptKid, Path input, Path output) throws AnkaSecureSdkException Signs then encrypts a file with forced compact format. Use when you need a single-line string for API/JSON transmission. Fails if the input exceeds the server's configured compact limit (maxPlaintextBytes, default 4 MB).When to Use Compact Format
- API transmission: Signed and encrypted data for JSON responses or HTTP headers
- Storage: Single database field (text/varchar) with both authenticity and confidentiality
- Interoperability: Nested JWE(JWS) standard format
Output Format
JWE( JWS(payload) )
Alternative Methods
Note: No streaming variant available for combined operations. For large files, split into separate sign and encrypt operations.
Example
// Sign and encrypt sensitive document SignEncryptResult result = sdk.signThenEncryptFileCompact( "my-ml-dsa-key", // Signing key "my-ml-kem-key", // Encryption key Path.of("contract.pdf"), Path.of("contract-secure.jwe") ); System.out.println("Signed with: " + result.getSignKeyRequested()); System.out.println("Encrypted with: " + result.getEncryptKeyRequested());- Parameters:
signKid- signing key identifier; must not benullencryptKid- encryption key identifier; must not benullinput- input file (up to the server's configured compact limit, default 4 MB); must not benulloutput- output file (.jwe); must not benull- Returns:
- operation result with metadata; never
null - Throws:
AnkaSecureSdkException- if the input exceeds the server's configured compact limit (HTTP 413) or operation failsDestinationExistsException- ifoutputalready exists and this instance usesOverwritePolicy.FAIL_IF_EXISTS(the default); callwithOverwrite()to overwrite
-
signThenEncryptFileCompact
public SignEncryptResult signThenEncryptFileCompact(String signKid, String encryptKid, Path input, Path output, JwsSerialization serialization) throws AnkaSecureSdkException Signs a file then encrypts it, explicitly selecting the inner-JWS serialization.Ergonomic overload of
signThenEncryptFileCompact(String, String, Path, Path). Passingnulldefers to the server.- Parameters:
signKid- private key identifier for signing; must not benullencryptKid- public key identifier for encryption; must not benullinput- input file; must not benulloutput- output file; must not benullserialization- requested inner-JWS serialization, ornullto defer- Returns:
- combined sign-encrypt result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 (before any signing or encryption) when COMPACT is requested but the deployment mandates a qualified timestamp- See Also:
-
signThenEncryptFileCompact
public SignEncryptResult signThenEncryptFileCompact(String signKid, String encryptKid, Path input, Path output, JwsSerialization serialization, SignOptions options) throws AnkaSecureSdkException Signs then encrypts a file (compact) with an explicit inner serialization and options for the inner signature.- Parameters:
signKid- identifier of the signing key; must not benullencryptKid- identifier of the encryption key; must not benullinput- plaintext file, up to the server's configured compact limit; must not benulloutput- destination of the nested JWE(JWS); must not benullserialization- requested inner-JWS serialization, ornullto let the server chooseoptions- the inner signature's options; must not benull- Returns:
- nested JWE(JWS) result; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 namingvalidityDayswhen it exceeds this deployment's maximum signature validity- See Also:
-
decryptThenVerifyFileCompact
public DecryptVerifyResult decryptThenVerifyFileCompact(Path input, Path output) throws AnkaSecureSdkException Decrypts and verifies a nested JWE(JWS) file with forced compact format. Use when you need to decrypt and verify a single-line string. Fails if the input exceeds the server's configured compact limit (maxPlaintextBytes, default 4 MB).When to Use Compact Format
- API transmission: Decrypting and verifying from JSON responses or HTTP headers
- Storage: Decrypting and verifying from single database field (text/varchar)
- Interoperability: Nested JWE(JWS) standard format
Alternative Methods
Note: No streaming variant available for combined operations. For large files, split into separate decrypt and verify operations.
Example
// Decrypt and verify secured document DecryptVerifyResult result = sdk.decryptThenVerifyFileCompact( Path.of("contract-secure.jwe"), Path.of("contract-recovered.pdf") ); if (result.isSignatureValid()) { System.out.println("Signature valid!"); result.getSignatureResults().forEach(signer -> System.out.println("Signed by: " + signer.getKid())); }Multi-key tokens: this form sends no
recipientKid, which the server reads as "the token names one key". For a JWE addressed to several keys it refuses the request with HTTP 400 namingrecipientKid; name the key withdecryptThenVerifyFileCompact(String, Path, Path).- Parameters:
input- nested JWE file (up to the server's configured compact limit, default 4 MB); must not benulloutput- recovered plaintext file; must not benull- Returns:
- operation result with verification status; never
null - Throws:
AnkaSecureSdkException- if the input exceeds the server's configured compact limit (HTTP 413) or operation failsDestinationExistsException- ifoutputalready exists and this instance usesOverwritePolicy.FAIL_IF_EXISTS(the default); callwithOverwrite()to overwrite
-
decryptThenVerifyFileCompact
public DecryptVerifyResult decryptThenVerifyFileCompact(String recipientKid, Path input, Path output) throws AnkaSecureSdkException Decrypts a nested JWE(JWS) file with the recipient the caller names, then verifies every signature of the inner JWS.Choosing the recipient and reading every signer
recipientKidnames the recipient of the outer JWE to decrypt with, exactly as fordecrypt(String, String); it must be none of the inner JWS's signers. Every signature of the inner JWS is verified under its own key, andDecryptVerifyResult.getSignatureResults()reports each of them in token order.Example
DecryptVerifyResult result = sdk.decryptThenVerifyFileCompact("custodian-b", Path.of("signed-minutes.jwe"), Path.of("signed-minutes.pdf"));- Parameters:
recipientKid- the key of the recipient to decrypt with;nullwhen the JWE names one key. Required when the JWE is addressed to several keysinput- nested JWE file; must not benulloutput- recovered plaintext file; must not benull- Returns:
- result with one entry per inner signature; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingrecipientKidwhen it is absent for an outer JWE addressed to several keys or names no recipient, HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when decryption or verification otherwise failsIllegalArgumentException- ifrecipientKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
signThenEncryptFileStream
public SignEncryptResult signThenEncryptFileStream(String signKid, String encryptKid, Path input, Path output) throws AnkaSecureSdkException Signs a file then encrypts it in streaming mode (nested JWE(JWS), bounded memory) — the large-file counterpart ofsignThenEncryptFileCompact(String, String, Path, Path).The payload is signed with
signKid(inner JWS) and the resulting JWS is encrypted withencryptKid(outer JWE) in a single incremental pass, so the signature is carried ENCRYPTED. The nested ciphertext artifact is written tooutputvia the SDK's sidecar write contract (quarantine to<output>.part, then atomic promotion). This is a PRODUCER operation — its result is deterministic (complete-or-abort), not verdict-framed. Because the artifact is streamed to disk,SignEncryptResult.getJweToken()isnullfor this variant; the artifact is theoutputfile.- Parameters:
signKid- private key identifier for signing (inner JWS); must not benullencryptKid- public key identifier for encryption (outer JWE); must not benullinput- input file to stream; must not benulloutput- output file for the nested JWE(JWS) artifact; must not benull- Returns:
- sign-encrypt result with the outer-JWE metadata; never
null - Throws:
AnkaSecureSdkException- if signing, encryption, or streaming failsDestinationExistsException- ifoutputalready exists and this instance usesOverwritePolicy.FAIL_IF_EXISTS(the default); callwithOverwrite()to overwrite- See Also:
-
signThenEncryptFileStream
public SignEncryptResult signThenEncryptFileStream(String signKid, String encryptKid, Path input, Path output, SignEncryptStreamOptions options) throws AnkaSecureSdkException Signs then encrypts a file in streaming mode with options: the inner signature's validity and the advisory flavor hint, sent in the request's metadata part. An option left unset is not sent.sdk.signThenEncryptFileStream("my-ml-dsa-key", "my-ml-kem-key", input, output, SignEncryptStreamOptions.builder().validityDays(90).flavor(SignEncryptFlavor.ASYMMETRIC).build());- Parameters:
signKid- identifier of the signing key; must not benullencryptKid- identifier of the encryption key; must not benullinput- plaintext file to stream; must not benulloutput- destination of the nested JWE(JWS); must not benulloptions- the request's options; must not benull(SignEncryptStreamOptions.none()sets nothing)- Returns:
- result carrying the outer-JWE metadata; never
null - Throws:
AnkaSecureSdkException- on error, including HTTP 400 namingvalidityDayswhen it exceeds this deployment's maximum signature validity- See Also:
-
decryptThenVerifyFileStream
public DecryptVerifyResult decryptThenVerifyFileStream(Path input, Path output) throws AnkaSecureSdkException Decrypts a nested JWE(JWS) file then verifies the inner signature in streaming mode — the large-file counterpart ofdecryptThenVerifyFileCompact(Path, Path), and the inverse ofsignThenEncryptFileStream(String, String, Path, Path).The server returns a TWO-verdict result carrying BOTH the outer AES-GCM tag outcome and the inner JWS signature outcome. The SDK quarantines the recovered plaintext to
<output>.partand promotes it tooutputONLY when the overall verdict is VALID (both dimensions passed). An INVALID or absent verdict is FAIL-CLOSED: the sidecar is deleted, no file is written, and a typedStreamIntegrityExceptionis thrown — success is never inferred from a closed socket. An INVALID verdict is its subclassDecryptVerifyIntegrityException, which names every inner signer with itsverifiedoutcome.On success,
DecryptVerifyResult.isSignatureValid()istrueandDecryptVerifyResult.getQualifiedTimestamp()surfaces the informational timestamp when present (it never affects validity).Multi-key tokens: this form sends no
recipientKid, which the server reads as "the token names one key". For a JWE addressed to several keys it refuses the request with HTTP 400 namingrecipientKid; name the key withdecryptThenVerifyFileStream(String, Path, Path).- Parameters:
input- nested JWE(JWS) streaming artifact (the output ofsignThenEncryptFileStream(String, String, Path, Path)); must not benulloutput- destination for the recovered plaintext; must not benull- Returns:
- decrypt-verify result with verification status and metadata; never
null - Throws:
AnkaSecureSdkException- if decryption or I/O fails. The JWET header is refused with HTTP 422 and no payload byte, before any key is looked up, when it carries a root member besidesprotected,recipients,iv,ciphertext,tagand, on a composite key's header,anka_composite_mode(JWE_ROOT_MEMBER_FORBIDDEN; a JSONaadmember and a sharedunprotectedheader included) or a recipient member besidesheaderandencrypted_key(JWE_RECIPIENT_MEMBER_FORBIDDEN). A header parameter name present both inprotectedand in a recipient header (RFC 7516 §7.2.1) is refused with HTTP 422 for a single-recipient JWE and HTTP 400 for a composite JWE or one addressed to several keys.StreamIntegrityException- if the integrity verdict is INVALID or absentDestinationExistsException- ifoutputalready exists and this instance usesOverwritePolicy.FAIL_IF_EXISTS(the default); callwithOverwrite()to overwrite- See Also:
-
decryptThenVerifyFileStream
public DecryptVerifyResult decryptThenVerifyFileStream(String recipientKid, Path input, Path output) throws AnkaSecureSdkException Decrypts a nested JWE(JWS) streaming artifact with the recipient the caller names, then verifies every signature of the inner JWS;recipientKidis sent as the query parameter of/crypto/stream/decrypt-verify. The fail-closed two-verdict contract ofdecryptThenVerifyFileStream(Path, Path)applies unchanged.Choosing the recipient and reading every signer
recipientKidnames the recipient of the outer JWE to decrypt with, exactly as fordecrypt(String, String); it must be none of the inner JWS's signers. Every signature of the inner JWS is verified under its own key, andDecryptVerifyResult.getSignatureResults()reports each of them in token order.The streaming route commits its response before the inner signers are known, so a signer that does not verify, or that the authenticated client holds no grant on, yields an INVALID verdict rather than the 400 or 403 of
decryptThenVerifyFileCompact(String, Path, Path). That outcome is aDecryptVerifyIntegrityExceptionwhosegetSignatureResults()names every signer with itsverifiedoutcome.Example
DecryptVerifyResult result = sdk.decryptThenVerifyFileStream("custodian-b", Path.of("signed-archive.jwet"), Path.of("signed-archive.tar"));- Parameters:
recipientKid- the key of the recipient to decrypt with;nullwhen the JWE names one key. Required when the JWE is addressed to several keysinput- nested JWE(JWS) streaming artifact; must not benulloutput- destination for the recovered plaintext; must not benull- Returns:
- result with one entry per inner signature; never
null - Throws:
AnkaSecureSdkException- with HTTP 400 namingrecipientKidwhen it is absent for an outer JWE addressed to several keys or names no recipient, HTTP 403 when the authenticated client holds no grant on a key the operation uses, or when decryption or verification otherwise fails. The JWET header is refused with HTTP 422 and no payload byte, before any key is looked up, when it carries a root member besidesprotected,recipients,iv,ciphertext,tagand, on a composite key's header,anka_composite_mode(JWE_ROOT_MEMBER_FORBIDDEN; a JSONaadmember and a sharedunprotectedheader included) or a recipient member besidesheaderandencrypted_key(JWE_RECIPIENT_MEMBER_FORBIDDEN). A header parameter name present both inprotectedand in a recipient header (RFC 7516 §7.2.1) is refused with HTTP 422 for a single-recipient JWE and HTTP 400 for a composite JWE or one addressed to several keys.DecryptVerifyIntegrityException- if the two-verdict result is INVALID, carrying the server's per-signer verdicts (no output is written)StreamIntegrityException- if the integrity verdict is absentIllegalArgumentException- ifrecipientKidis empty or blank (passnullwhen the token names one key); nothing is sent- See Also:
-
analyzePkcs7
public co.ankatech.secure.client.model.Pkcs7AnalysisResponse analyzePkcs7(co.ankatech.secure.client.model.Pkcs7AnalysisRequest request) throws AnkaSecureSdkException Analyzes a PKCS#7 file to extract metadata and certificate information.Parses a PKCS#7/CMS structure and returns its detected format, its signers and recipients, the support status, the conversion recommendations and the analysis limits, without verifying any signature or decrypting any content.
Example
byte[] der = java.nio.file.Files.readAllBytes( java.nio.file.Path.of("/legacy/contract-signed.p7s")); co.ankatech.secure.client.model.Pkcs7AnalysisRequest request = new co.ankatech.secure.client.model.Pkcs7AnalysisRequest() .pkcs7Data(java.util.Base64.getEncoder().encodeToString(der)); co.ankatech.secure.client.model.Pkcs7AnalysisResponse analysis = sdk.analyzePkcs7(request); System.out.println("Structure: " + analysis.getDetectedFormat().getStructure()); System.out.println("Actor limit: " + analysis.getLimits().getMaxActors()); if (analysis.getSigners() != null) { analysis.getSigners().forEach(s -> System.out.println("Signer: " + s.getIssuerDN() + " (" + s.getSignatureAlgorithm() + ")")); } if (analysis.getRecipients() != null) { System.out.println("Recipients: " + analysis.getRecipients().size()); } if (analysis.getRecommendations() != null) { System.out.println("Migration path: " + analysis.getRecommendations().getMigrationPath()); }- Parameters:
request- PKCS#7 analysis request; must not benull- Returns:
- analysis result containing PKCS#7 metadata; never
null - Throws:
AnkaSecureSdkException- if the file cannot be read, is not valid PKCS#7, or the server returns an errorNullPointerException- ifrequestisnull
-
analyzePkcs7Stream
public co.ankatech.secure.client.model.Pkcs7AnalysisResponse analyzePkcs7Stream(File file) throws AnkaSecureSdkException Analyzes a PKCS#7 file using streaming to avoid loading the entire file into memory.Example
java.io.File file = new java.io.File("/legacy/large-signed-archive.p7s"); co.ankatech.secure.client.model.Pkcs7AnalysisResponse analysis = sdk.analyzePkcs7Stream(file);Analysis is structural: it decrypts nothing and validates no certificate path or timestamp, so it takes no key and no option. The request still carries a
metadatapart, the empty JSON object, beforefile: the server reads the body single-pass and cannot rewind, so afile-first body, or one omittingmetadata, is refused with400 .../errors/multipart-part-orderbefore any payload byte is read. The SDK always emits that part; the caller supplies only the file.- Parameters:
file- PKCS#7 file to analyze; must not benull- Returns:
- analysis result containing PKCS#7 metadata; never
null - Throws:
AnkaSecureSdkException- if the file cannot be read or is not valid PKCS#7, or the server returns an errorNullPointerException- iffileisnull
-
convertPkcs7ToJose
public co.ankatech.secure.client.model.Pkcs7ConversionResponse convertPkcs7ToJose(co.ankatech.secure.client.model.Pkcs7ConversionRequest request) throws AnkaSecureSdkException Converts a PKCS#7 signature to JOSE (JWS) format.Extracts the signature from a PKCS#7/CMS file and converts it to compact JWS (RFC 7515) format. This enables legacy PKCS#7 signatures to be verified using modern JOSE tooling.
Authorization. Besides the
migration.convertPkcs7scope, the calling Cryptographic Actor needs a Capability Grant per leg, decided with the re-operation capabilities:REENCRYPTover[opener, recipient]for every other recipient and over the opener's own in-place pair (the opener beingdecryptionKid, or the first recipient whose key can decrypt), andRESIGNover each signer's in-place pair. A REENCRYPT/RESIGN grant is requested with exactly twoassetKids: an in-place pair names the kid twice ([kid, kid], stored as[kid]), a cross pair is[opener, recipient], and there is no wildcard re-operation grant. A grant admits any request whose kids it contains, so the[opener, recipient]grant also covers the opener's in-place leg. ENCRYPT, DECRYPT and SIGN grants admit no conversion; a missing grant is refused with HTTP 403. Grants are created on the control plane.Example
co.ankatech.secure.client.model.Pkcs7ConversionRequest request = new co.ankatech.secure.client.model.Pkcs7ConversionRequest() .pkcs7Data(base64Pkcs7); co.ankatech.secure.client.model.Pkcs7ConversionResponse conversion = sdk.convertPkcs7ToJose(request); String jws = conversion.getJoseToken(); System.out.println("Converted to JWS: " + jws);- Parameters:
request- PKCS#7 conversion request; must not benull- Returns:
- conversion result containing JWS token; never
null - Throws:
AnkaSecureSdkException- if the file cannot be read, is not valid PKCS#7, conversion fails, or the server returns an errorNullPointerException- ifrequestisnull
-
convertPkcs7ToJoseStream
public File convertPkcs7ToJoseStream(co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest metadata, File inputFile, File outputFile) throws AnkaSecureSdkException Converts a PKCS#7 signature to JOSE using streaming.Authorization. Besides the
migration.convertPkcs7scope, the calling Cryptographic Actor needs a Capability Grant per leg, decided with the re-operation capabilities:REENCRYPTover[opener, recipient]for every other recipient and over the opener's own in-place pair (the opener beingdecryptionKid, or the first recipient whose key can decrypt), andRESIGNover each signer's in-place pair. A REENCRYPT/RESIGN grant is requested with exactly twoassetKids: an in-place pair names the kid twice ([kid, kid], stored as[kid]), a cross pair is[opener, recipient], and there is no wildcard re-operation grant. A grant admits any request whose kids it contains, so the[opener, recipient]grant also covers the opener's in-place leg. ENCRYPT, DECRYPT and SIGN grants admit no conversion; a missing grant is refused with HTTP 403. Grants are created on the control plane.Example
co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest metadata = new co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest(); java.io.File inputFile = new java.io.File("/legacy/large-signed-archive.p7s"); java.io.File outputFile = new java.io.File("/converted/signature.jws"); java.io.File result = sdk.convertPkcs7ToJoseStream(metadata, inputFile, outputFile);- Parameters:
metadata- conversion metadata; must not benullinputFile- path to PKCS#7 file; must not benulland file must existoutputFile- path where JWS will be written; must not benull- Returns:
- the output file; never
null - Throws:
AnkaSecureSdkException- if the file cannot be read, is not valid PKCS#7, conversion fails, or the server returns an errorNullPointerException- if any parameter isnull
-
performMigrationWorkflow
public MigrationWorkflowResult performMigrationWorkflow(File pkcs7File, co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest conversionRequest, File outputFile) throws AnkaSecureSdkException Performs a complete PKCS#7-to-JOSE migration workflow with analysis and conversion.Analyzes a PKCS#7 file, converts it to JOSE format, and writes the result. This is a complete end-to-end workflow for migrating legacy PKCS#7 signatures to modern JOSE format.
Authorization. The conversion step is authorized as
convertPkcs7ToJoseStream(co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest, java.io.File, java.io.File): besides themigration.convertPkcs7scope, the calling Cryptographic Actor needs a Capability Grant per leg, decided with the re-operation capabilities:REENCRYPTover[opener, recipient]for every other recipient and over the opener's own in-place pair (the opener beingdecryptionKid, or the first recipient whose key can decrypt), andRESIGNover each signer's in-place pair. A REENCRYPT/RESIGN grant is requested with exactly twoassetKids: an in-place pair names the kid twice ([kid, kid], stored as[kid]), a cross pair is[opener, recipient], and there is no wildcard re-operation grant. A grant admits any request whose kids it contains, so the[opener, recipient]grant also covers the opener's in-place leg. ENCRYPT, DECRYPT and SIGN grants admit no conversion; a missing grant is refused with HTTP 403. Grants are created on the control plane.Example
java.io.File pkcs7 = new java.io.File("/legacy/signed.p7s"); java.io.File output = new java.io.File("/converted/signed.jws"); co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest request = new co.ankatech.secure.client.model.Pkcs7ConversionStreamRequest(); MigrationWorkflowResult result = sdk.performMigrationWorkflow(pkcs7, request, output); System.out.println("Migration complete");- Parameters:
pkcs7File- the PKCS#7 file to convert; must not benullconversionRequest- the conversion parameters; must not benulloutputFile- where to write the JOSE output; must not benull- Returns:
- migration result with details; never
null - Throws:
AnkaSecureSdkException- if the workflow fails or the server returns an errorNullPointerException- if any parameter isnull- See Also:
-
encryptFileUtilityStream
public EncryptResult encryptFileUtilityStream(String kty, String alg, String publicKeyB64, Path input, Path output) throws AnkaSecureSdkException Encrypts a file using a provided public key (without requiring key in ANKASecure).This utility method allows encryption using an externally-managed public key, bypassing the normal key management workflow. Useful for one-off encryptions or interoperability with external systems.
Example
String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."; EncryptResult result = sdk.encryptFileUtilityStream( "RSA", "RSA-OAEP", publicKeyBase64, Path.of("/data/document.pdf"), Path.of("/data/document.pdf.jwe") );- Parameters:
kty- key type (e.g., "RSA", "EC", "ML-KEM"); must not benullalg- algorithm (e.g., "RSA-OAEP", "ML-KEM-768"); must not benullpublicKeyB64- base64-encoded public key; must not benullinput- path to plaintext file; must not benulloutput- path where JWE will be written; must not benull- Returns:
- encryption result containing operation metadata; never
null - Throws:
AnkaSecureSdkException- if the key is invalid, algorithm is unsupported, files cannot be read/written, or the server returns an errorNullPointerException- if any parameter isnull
-
verifySignatureUtilityStream
public VerifySignatureResult verifySignatureUtilityStream(String kty, String alg, String publicKeyB64, String signatureB64, Path dataFile) throws AnkaSecureSdkException Verifies a signature using a provided public key (without requiring key in ANKASecure).This utility method allows signature verification using an externally-managed public key, bypassing the normal key management workflow. Useful for verifying signatures from external systems.
Example
String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."; String signatureBase64 = "..."; VerifySignatureResult result = sdk.verifySignatureUtilityStream( "RSA", "RS256", publicKeyBase64, signatureBase64, Path.of("/data/document.pdf") ); if (result.isValid()) { System.out.println("Signature verified"); }- Parameters:
kty- key type (e.g., "RSA", "EC", "ML-DSA"); must not benullalg- algorithm (e.g., "RS256", "ML-DSA-65"); must not benullpublicKeyB64- base64-encoded public key; must not benullsignatureB64- base64-encoded signature; must not benulldataFile- path to original data file; must not benull- Returns:
- verification result containing validity status; never
null - Throws:
AnkaSecureSdkException- if the key is invalid, algorithm is unsupported, files cannot be read, or the server returns an errorNullPointerException- if any parameter isnull
-
getSupportedAlgorithms
Retrieves the complete list of cryptographic algorithms supported by the server.Returns all algorithms available for key generation, encryption, signing, and other cryptographic operations. Each
AlgorithmInfoincludes detailed metadata about the algorithm's characteristics, security level, and supported operations.Example
List<AlgorithmInfo> allAlgorithms = sdk.getSupportedAlgorithms(); // Find all post-quantum algorithms allAlgorithms.stream() .filter(alg -> alg.getCategory().equals("POST_QUANTUM")) .forEach(alg -> System.out.println(alg.getKty() + " / " + alg.getAlg() + " (Level " + alg.getSecurityLevel() + ")") );- Returns:
- list of all supported algorithm information; never
null, never empty - Throws:
AnkaSecureSdkException- if the server returns an error or the request fails- See Also:
-
getCryptoLimits
Returns the compact-crypto limit this instance applies, and where it came from.CryptoLimits.maxPlaintextBytes()is the largest payload a compact operation accepts for the caller's tenant (GET /api/v3/crypto/limits); the automatic compact/streaming choice of the*Filemethods uses this same value. The value is read at most once a minute. When it cannot be read, this method does not throw: it returns the SDK's default with sourceCryptoLimits.Source.DEFAULT_AFTER_FAILURE, and the failure is logged at WARN.CryptoLimits limits = sdk.getCryptoLimits(); if (limits.source() == CryptoLimits.Source.SERVER && Files.size(file) < limits.maxPlaintextBytes()) { sdk.encryptFileCompact(kid, file, output); }- Returns:
- the limit and its source; never
null
-
getSupportedAlgorithms
public List<AlgorithmInfo> getSupportedAlgorithms(AlgorithmFilter filter) throws AnkaSecureSdkException Retrieves cryptographic algorithms matching the specified filter criteria.Filters the algorithm catalog by category (classical, post-quantum, hybrid), key operations (encrypt, sign, etc.), security level, and other characteristics. Multiple filter criteria are combined with AND logic.
Example
// Find all NIST Level 5 post-quantum signing algorithms AlgorithmFilter filter = AlgorithmFilter.builder() .withCategory(AlgorithmInfo.Category.POST_QUANTUM) .withKeyOps("sign", "verify") .withSecurityLevel(5) .build(); List<AlgorithmInfo> pqcSigning = sdk.getSupportedAlgorithms(filter); pqcSigning.forEach(alg -> System.out.println(alg.getKty() + " / " + alg.getAlg() + " (Level " + alg.getSecurityLevel() + ")") ); // Use the first result to drive a data-plane operation if (!pqcSigning.isEmpty()) { AlgorithmInfo chosen = pqcSigning.get(0); System.out.println("Selected algorithm: " + chosen.getKty() + " / " + chosen.getAlg()); }- Parameters:
filter- the algorithm filter specifying criteria such as category, key operations, and security level; must not benull- Returns:
- list of algorithm information matching all specified filter criteria;
never
null, may be empty if no algorithms match - Throws:
AnkaSecureSdkException- if the server returns an error or the request failsNullPointerException- iffilterisnull- See Also:
-