[Release] GroupDocs.Signature for Java 26.10

Dear GroupDocs users, we’re pleased to announce GroupDocs.Signature for Java 26.10. This release makes signing and verification safer by default: external resources referenced by documents are no longer loaded, expired signing certificates are rejected, PDF digital signatures use SHA-256 and are verified cryptographically, and archives are checked while they are expanded. It also adds OOXML compliance for Word documents and working certificate verification, fixes barcode and QR-code signing on Java 11 and later, logging, archive search and verification, and brings the Aspose libraries up to date. Several changes alter existing behaviour, so please review the section below before upgrading.

Behaviour changes to check before upgrading

  • External resources referenced by a document are not loaded unless LoadOptions.setSkipExternalResources(false) is set.
  • Signing with an expired or not yet valid certificate throws GroupDocsSignatureException; set DigitalSignOptions.setAllowExpired(true) or setAllowNotYetValid(true) to sign anyway.
  • PDF digital signatures are created with SHA-256 (adbe.pkcs7.detached) instead of SHA-1.
  • Verifying a PDF with DigitalVerifyOptions reports a signature as valid only if it verifies cryptographically, and applies SubjectName, IssuerName and the signing time window.
  • With the default LogLevel.All, a logger passed in SignatureSettings now receives messages; before, nothing was logged.
  • An archive with more than 10,000 entries, more than 1 GB of content or an entry compressed more than 100 times is rejected.
  • The jar is no longer signed with jarsigner; detached .asc PGP signatures are published next to it.

Feature — control over loading external resources

A document can reference resources outside itself, such as an image given by a remote URL, a picture linked to a file or a style sheet referenced from an SVG, and opening it used to make the library fetch that address. External resources are now skipped by default. LoadOptions.setSkipExternalResources(boolean) turns loading back on, and setWhitelistedResources(List<String>) names address fragments that are still loaded while the rest are skipped.

LoadOptions loadOptions = new LoadOptions();
loadOptions.setSkipExternalResources(true);
loadOptions.setWhitelistedResources(Arrays.asList("cdn.example.com/logo.png"));

Signature signature = new Signature("contract.docx", loadOptions);
try {
    signature.sign("contract_signed.docx", new TextSignOptions("John Smith"));
} finally {
    signature.dispose();
}

The settings apply to Word, presentation, spreadsheet and SVG documents, and documents inside an archive get the archive’s settings. LoadOptions.setLoadExternalResources is deprecated; it is now the inverse of the new setting, so its default changes from true to false. (SIGNATURENET-5950, SIGNATURENET-6000, SIGNATURENET-6001)

Feature — expired and not yet valid signing certificates

A digital signature made with a certificate whose validity period has ended, or has not started, is now rejected before the document is loaded. The message names the certificate by subject and thumbprint and says which property allows it. DigitalSignOptions.setAllowExpired(true) and setAllowNotYetValid(true) sign anyway and log a warning. The check covers every document type and the certificate of a VBA project in a spreadsheet. (SIGNATURENET-5995)

Feature — SHA-256 PDF digital signatures and cryptographic verification

PDF digital signatures were created as adbe.pkcs7.sha1, whose digest is fixed at SHA-1, and SignOptions.setHashAlgorithm was ignored. They are now created as adbe.pkcs7.detached with SHA-256, and HashAlgorithm selects another digest, including for the time stamp. (SIGNATURENET-5976)

Verifying a PDF with DigitalVerifyOptions used to compare only the criteria that were set, so with no criteria any PDF with a signature field was valid, even after the document was changed. Each signature is now verified first and is valid only if that check passes. SubjectName, IssuerName, SignDateTimeFrom and SignDateTimeTo, which were accepted and ignored for PDF, are applied as they already were for Word documents. (SIGNATURENET-5978, SIGNATURENET-5997)

DigitalVerifyOptions options = new DigitalVerifyOptions();
options.setSubjectName("John Smith");

Signature signature = new Signature("contract_signed.pdf");
try {
    VerificationResult result = signature.verify(options);
    System.out.println(result.isValid());  // false if the document was changed after signing
} finally {
    signature.dispose();
}

Feature — OOXML compliance and certificate verification

A Word document saved after signing now keeps the OOXML compliance it was loaded with, and WordProcessingSaveOptions.setOoxmlCompliance(OoxmlCompliance.Strict) (or Ecma, Transitional) sets another one. (SIGNATURENET-5634)

Verifying a certificate file with CertificateVerifyOptions computed nothing. It now checks Expired, the issuer, subject, serial number and thumbprint with the option’s MatchType, and with PerformChainValidation builds a path to the Java trust store. (SIGNATURENET-6003)

Fix — barcode and QR-code signing on Java 11 and later

Signing presentations and spreadsheets with barcode or QR-code options failed with Cannot open an image. The image size can not be 0!. The signature image was written as JPEG, which the JPEG writer of Java 11 and later refuses for images with transparency. Java 8 was not affected, which made the failure look specific to Linux or Docker. The image is now written as PNG. (SIGNATUREJAVA-2903)

Fix — logging

SignatureSettings.setLogLevel compared the level for equality instead of as a set of flags, so with the default LogLevel.All nothing was logged and combined values such as LogLevel.Error | LogLevel.Warning never matched. Logging now follows the level; set LogLevel.None or a narrower level if your logger receives more than you need. (SIGNATURENET-6004)

Fix — archives and reused options

Search of an archive failed with a NullPointerException, and verification of an archive always failed; both work now. A VerifyOptions object used for several documents kept the signatures of documents verified earlier, and a DigitalSignOptions object used for several presentations signed later ones with the first certificate; each call now uses only its own document and settings. (SIGNATUREJAVA, SIGNATURENET-6005, SIGNATURENET-6006)

Other fixes

  • A custom PDF signer set with DigitalSignOptions.setCustomSignHash is called, and the built-in signers produce signatures that verify. (SIGNATURENET-5208)
  • The time-stamp server receives credentials when only the user name or only the password is set. (SIGNATURENET-5998)
  • Spreadsheets with a linked picture that has no image data no longer fail search and verification. (SIGNATURENET-6002)
  • Certificates whose key entry has a name — most PFX files — are accepted for presentations, spreadsheets and VBA projects.
  • Saving a signed document as images no longer produces empty pages.
  • JPEG, PNG, GIF and TIFF save options such as the JPEG quality are applied.
  • ReturnContentType is honoured: FileType.equals returned true for any two types.
  • QR-code search in multi-layer images with ReturnContent returns the codes found.
  • BarcodeTypes.GS1CompositeBar has a default text that Aspose.BarCode accepts.
  • Passing options of the wrong type reports the validation error instead of a FormatException.

Other updates

  • Archives are checked while they are expanded; one beyond the limits fails with GroupDocsSignatureException caused by ArchiveSecurityException.
  • LoadOptions.setFileType, Signature.search(Predicate<BaseSignature>) and VerificationResult.getFailed() are available, as in .NET.
  • The Aspose libraries are updated to the versions used by GroupDocs.Total. BarcodeTypes.Code39, Code39FullASCII and Code93 replace the Standard and Extended types, which remain as deprecated aliases.
  • In evaluation mode, signing an archive is no longer limited by the number of documents in it. (SIGNATURENET-5825)
  • The jar declares Automatic-Module-Name: com.groupdocs.signature and ships its third-party licences; the published POM carries licence, developer, organisation and scm details; and the license agreement and links in the distribution package point at addresses that exist. (SIGNATUREJAVA-2905, SIGNATUREJAVA-2906, SIGNATUREJAVA-2925)

Resources