GroupDocs.Signature for Java 26.5 Release Notes

The release of GroupDocs.Signature version 26.5 adds new feature and enhancement.

Full list of changes in this release

KeyCategorySummary
SIGNATURENET-5077★ FeatureAdd Resolution property to PreviewOptions
SIGNATURENET-5208★ FeatureAdd ICustomSignHash plug-in for PDF digital signing
SIGNATURENET-5217★ FeatureAdd search and verify methods with Predicate filters
SIGNATURENET-5218★ FeatureAdd search and verify methods with Predicate filters
SIGNATURENET-5242🔧 FixFix invisible image in PDF digital signature
SIGNATURENET-5267★ FeatureAdd PDF permissions and security on save
SIGNATURENET-5270🔧 FixRespect existing digital signatures when adding new ones to PDF
SIGNATURENET-5291🔧 FixRecognize legacy barcode type names when matching persisted signatures
SIGNATURENET-5364★ FeatureAdd UseLtv support for PDF digital signatures (Long Term Validation)
SIGNATURENET-5527🔧 FixFix “file type not supported” while searching signatures in WebP images
SIGNATURENET-5571★ FeatureAdd digital signing of raster images via LSB steganography
SIGNATUREJAVA-WORDS-LARGE-RUNSEnhancementHandle Word documents with large text shapes spanning multiple pages

Major Features

This release brings six new functional features for digital signing and document signature search, plus a critical PDF-integrity fix:

Add Resolution property to PreviewOptions

🌐 A new resolution property has been added to PreviewOptions allowing callers to control the DPI of generated preview images. The default value is 96 DPI (the previous hard-coded behaviour). The new resolution is honoured across every previewer: PDF, Words, Spreadsheet (Excel), Presentation (Slides), Images and ImageLayers. As a bonus, Excel previews now use the actual sheet dimensions (SheetRender.getPageSizeInch × resolution) so spreadsheet previews are no longer cropped at unexpected sizes.

Signature signature = new Signature(filePath);

PreviewOptions previewOptions = new PreviewOptions(pageStreamFactory);
// Override the default 96 DPI — render previews at print quality
previewOptions.setResolution(300);
previewOptions.setPreviewFormat(PreviewFormats.PNG);

signature.generatePreview(previewOptions);

Add UseLtv support for PDF digital signatures (Long Term Validation)

🌐 A new useLtv flag has been added to DigitalSignOptions. When set to true, GroupDocs.Signature embeds the LTV (Long Term Validation) revocation information into the resulting PDF, so the digital signature stays verifiable long after the signing certificate expires. The default is false (backwards-compatible behaviour).

Signature signature = new Signature(pdfFilePath);

DigitalSignOptions options = new DigitalSignOptions(certificateFilePath);
options.setPassword("1234567890");
options.setReason("Approved");
options.setContact("John Smith");
options.setLocation("Office");
// Enable Long Term Validation — embeds OCSP / CRL data into the signature
options.setUseLtv(true);

signature.sign(outputFilePath, options);

Add search and verify methods with Predicate filters

🌐 Four new overloads have been added to the Signature class that accept a java.util.function.Predicate<T> filter, letting callers narrow down search and verify results without writing post-processing loops:

  • search(Class<T>, SearchOptions, Predicate<T>)
  • search(List<SearchOptions>, Predicate<BaseSignature>)
  • verify(VerifyOptions, Predicate<BaseSignature>)
  • verify(List<VerifyOptions>, Predicate<BaseSignature>)
Signature signature = new Signature(filePath);

// Typed search filtered by an arbitrary predicate
List<TextSignature> matches = signature.search(
    TextSignature.class,
    new TextSearchOptions(),
    sig -> "John Smith".equals(sig.getText())
);

// Multi-option search returning a SearchResult filtered by predicate
List<SearchOptions> queries = new ArrayList<SearchOptions>();
queries.add(new TextSearchOptions());
queries.add(new BarcodeSearchOptions());
SearchResult result = signature.search(
    queries,
    sig -> sig.getSignatureType() == SignatureType.Text
);

// Verify and keep only the signatures that pass an additional check
List<BaseSignature> trusted = signature.verify(
    new DigitalVerifyOptions(),
    sig -> sig.isValid() && "ACME Corp".equals(((DigitalSignature) sig).getSignatureId())
);

Add PDF permissions and security on save

🌐 Two new properties have been added to PdfSaveOptionspermissions (an Integer flags value composed from com.groupdocs.signature.options.Permissions) and permissionsPassword (the PDF owner password). Together they let callers protect the output PDF without going through a separate Aspose.PDF step. The library encrypts the output with AES-256 when either property is set. LoadOptions also exposes a new read-only permissions field that is automatically populated when a PDF is opened, so callers can inspect existing restrictions before re-signing.

The Permissions flags type defines the allowed denials:

DenyPrinting        // deny printing of the document
DenyModification    // deny content modification, form fill, annotations
DenyDataExtraction  // deny text / graphics extraction
DenyAll             // shorthand for all of the above
Signature signature = new Signature(sourceFilePath);

// Build sign options
TextSignOptions signOptions = new TextSignOptions("John Smith");
signOptions.setLeft(100);
signOptions.setTop(100);

// Protect the output PDF: open password + owner password + restriction flags
PdfSaveOptions saveOptions = new PdfSaveOptions();
saveOptions.setPassword("openPass");
saveOptions.setPermissionsPassword("ownerPass");
saveOptions.setPermissions(
    Permissions.DenyPrinting
  | Permissions.DenyModification
);

signature.sign(outputFilePath, signOptions, saveOptions);
// On load, inspect the permissions already encoded in the source document
LoadOptions loadOptions = new LoadOptions();
loadOptions.setPassword("openPass");

Signature signature = new Signature(filePath, loadOptions);
Integer existingPerms = loadOptions.getPermissions();
if (existingPerms != null
        && (existingPerms & Permissions.DenyPrinting) == Permissions.DenyPrinting) {
    System.out.println("Source PDF disallows printing");
}

Add digital signing of raster images via LSB steganography

🌐 Two new option classes — ImageDigitalSignOptions and ImageDigitalVerifyOptions — have been added to embed and verify digital signatures inside raster images (PNG, JPG, TIFF) using least-significant-bit steganography. The signature is invisible to the eye but verifiable with the original password. A minimum image size of 8×8 pixels and 16384 total pixels is enforced.

// Embed an LSB digital signature into a PNG
Signature signature = new Signature("photo.png");

ImageDigitalSignOptions signOptions = new ImageDigitalSignOptions("secret1234");

signature.sign("photo_signed.png", signOptions);
// Verify the embedded signature
Signature verifier = new Signature("photo_signed.png");

ImageDigitalVerifyOptions verifyOptions = new ImageDigitalVerifyOptions("secret1234");
// Optional: tune sensitivity (default is 75 %)
verifyOptions.setDetectionThresholdPercent(80);
// Optional: full extraction with detection probability reported back
verifyOptions.setUseFullDataExtraction(true);

VerificationResult result = verifier.verify(verifyOptions);
if (result.isValid()) {
    System.out.println("Image is digitally signed.");
    Integer probability = verifyOptions.getDetectedProbability();
    if (probability != null) {
        System.out.println("Detection confidence: " + probability + "%");
    }
}

Add ICustomSignHash plug-in for PDF digital signing

🌐 A new plug-in interface ICustomSignHash lets callers delegate the actual PDF digital-signing hash computation to an external signer — Hardware Security Modules (HSM), remote signing services, smart cards, or any custom key store. The implementation receives the bytes to sign, the chosen HashAlgorithm and a SignatureContext exposing the originating SignOptions. The signed blob it returns is embedded into the PDF.

New helper types:

  • com.groupdocs.signature.domain.enums.HashAlgorithm — flag-int constants Sha256 / Sha384 / Sha512
  • com.groupdocs.signature.options.sign.signhash.ICustomSignHash — the interface
  • com.groupdocs.signature.options.sign.signaturecontext.SignatureContext — context passed to every invocation
  • DigitalSignOptions.setCustomSignHash(...) — installs the custom signer
  • SignOptions.setHashAlgorithm(int) — selects the hash algorithm
// Implement your own signer (HSM, KMS, smartcard, ...)
public class MyHsmSignHash implements ICustomSignHash {
    @Override
    public byte[] customSignHash(byte[] signableHash,
                                 int hashAlgorithm,
                                 SignatureContext context) throws Exception {
        // Forward the hash to the HSM and return the raw PKCS#1 signature.
        return myHsmClient.sign(signableHash);
    }
}
// Use the plug-in
Signature signature = new Signature(pdfFilePath);

DigitalSignOptions options = new DigitalSignOptions(certificateFilePath);
options.setPassword("certPass");
options.setHashAlgorithm(HashAlgorithm.Sha256);
options.setCustomSignHash(new MyHsmSignHash());

signature.sign(outputFilePath, options);

Fix invisible image in PDF digital signature

🌐 We’ve addressed a bug where a custom image attached to a PDF digital signature appearance was effectively hidden behind the default SystemColors.Window background of PdfDigitalSignatureAppearance. The default background is now Color.Transparent, so the image you assign through DigitalSignOptions.setImageFilePath(...) or DigitalSignOptions.setImageStream(...) shows through the appearance pane unchanged.

Signature signature = new Signature(pdfFilePath);

DigitalSignOptions options = new DigitalSignOptions(certificateFilePath);
options.setPassword("1234567890");
options.setImageFilePath("signature-image.png");   // now visible by default
options.setReason("Approved");

signature.sign(outputFilePath, options);

Respect existing digital signatures when adding new ones to PDF

🌐 Previously, signing a PDF that already contained one or more digital signatures invalidated those prior signatures — the save pipeline always re-wrote the document, mutating its metadata block and therefore breaking the integrity hash of every existing signature. From this release, when the only thing the caller asks for is adding digital signatures to a PDF that already carries digital certificates, the metadata write and the intermediate re-save are skipped so existing signatures stay valid.

// Source PDF already contains one or more digital signatures from a previous signer.
Signature signature = new Signature(pdfWithExistingSignature);

DigitalSignOptions options = new DigitalSignOptions(certificateFilePath);
options.setPassword("certPass");
options.setReason("Counter-signed by approver");

signature.sign(outputFilePath, options);
// The new signature is appended; every signature already present in the source
// PDF remains cryptographically valid afterwards.

Handle Word documents with large text shapes spanning multiple pages

🌐 Word documents whose individual runs span more than one page (large text shapes, big tables or wide images) used to confuse the signature placement logic — it relied on the run’s start page only and silently lost signatures whose target page fell inside such a run. The compositor and the text-stamp implementation now detect “large nodes” that begin on a non-target page but end on a target page, and place the signature on the end page using the node’s parent as the insertion anchor. No API change — existing signing code works against multi-page-run documents out of the box.