GroupDocs.Signature for Java 26.10 Release Notes
Full list of changes in this release
| ID | Summary | Category |
|---|---|---|
| SIGNATURENET-5950, SIGNATURENET-6000, SIGNATURENET-6001 | External resources referenced by a document are no longer loaded by default; new LoadOptions settings control it | Feature |
| SIGNATURENET-5995 | Signing with an expired or not yet valid certificate is rejected unless DigitalSignOptions allows it | Feature |
| SIGNATURENET-5634 | Word documents keep their OOXML compliance when saved; WordProcessingSaveOptions can set it | Feature |
| SIGNATURENET-5976 | PDF digital signatures use SHA-256 by default and honour HashAlgorithm | Feature |
| SIGNATURENET-5978 | Verify checks PDF digital signatures cryptographically; a document changed after signing is not valid | Feature |
| SIGNATURENET-5997 | PDF verification honours SubjectName, IssuerName and the signing time window | Feature |
| SIGNATURENET-6003 | Certificate verification checks Expired, issuer, subject, serial number, thumbprint and the chain | Feature |
| SIGNATUREJAVA | LoadOptions.setFileType, Signature.search(Predicate) and VerificationResult.getFailed(), as in .NET | Feature |
| SIGNATURENET-6004 | SignatureSettings.setLogLevel takes effect; with the default level the logger now receives messages | Fix |
| SIGNATUREJAVA-2903 | Barcode and QR-code signing no longer fails with The image size can not be 0! on Java 11 and later | Fix |
| SIGNATURENET-5208 | A custom PDF signer (ICustomSignHash) is called, and the signature it produces verifies | Fix |
| SIGNATURENET-5998 | The time-stamp server receives credentials when only the user name or only the password is set | Fix |
| SIGNATURENET-6005 | A VerifyOptions object used for several documents reports only the current document | Fix |
| SIGNATURENET-6006 | A DigitalSignOptions object used for several presentations signs each one with its own settings | Fix |
| SIGNATURENET-6002 | Spreadsheets with a linked picture that has no image data no longer fail search and verification | Fix |
| SIGNATUREJAVA | Search and verification of archives work | Fix |
| SIGNATUREJAVA | Certificates whose key entry has a name are accepted for presentations, spreadsheets and VBA projects | Fix |
| SIGNATUREJAVA | Saving a signed document as images no longer produces empty pages | Fix |
| SIGNATUREJAVA | Image save options (JPEG quality, PNG, GIF and TIFF settings) are applied | Fix |
| SIGNATUREJAVA | ReturnContentType is honoured; FileType.equals compares the types | Fix |
| SIGNATUREJAVA | QR-code search in multi-layer images with ReturnContent returns the codes found | Fix |
| SIGNATUREJAVA | BarcodeTypes.GS1CompositeBar has a default text that Aspose.BarCode accepts | Fix |
| SIGNATUREJAVA | Passing options of the wrong type reports the validation error instead of a FormatException | Fix |
| SIGNATUREJAVA | Archives are checked for excessive size and compression while they are expanded | Update |
| SIGNATURENET-5825 | Trial limits: signing an archive is no longer limited by the number of documents in it | Update |
| SIGNATUREJAVA-2908 | Aspose libraries updated; BarcodeTypes.Code39, Code39FullASCII and Code93 replace the Standard/Extended types | Update |
| SIGNATUREJAVA-2905 | The jar declares Automatic-Module-Name, ships its third-party licences and is signed with detached PGP signatures | Update |
| SIGNATUREJAVA-2906 | Published POM: product name and description, licence, developers, organisation and scm | Update |
| SIGNATUREJAVA-2925 | The license agreement and links in the distribution package point at addresses that exist | Update |
Behaviour changes to check before upgrading
Several changes alter what existing code observes. Each is described in its own section below.
- External resources are not loaded unless
LoadOptions.setSkipExternalResources(false)is set. - Signing with an expired or not yet valid certificate throws
GroupDocsSignatureException. SetDigitalSignOptions.setAllowExpired(true)orsetAllowNotYetValid(true)to sign anyway. - PDF digital signatures are created with SHA-256 (
adbe.pkcs7.detached) instead of SHA-1. - Verifying a PDF with
DigitalVerifyOptionsreports a signature as valid only if it verifies cryptographically, and appliesSubjectName,IssuerName,SignDateTimeFromandSignDateTimeTo. - With the default
LogLevel.All, a logger passed inSignatureSettingsnow receives errors, warnings and trace 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.ascPGP signatures are published next to it.
Feature — control over loading external resources
A document can reference resources outside itself — for example an image given by a remote URL, a picture linked to a file, or a style sheet referenced from an SVG. Opening it used to make the library fetch that address. External resources are now skipped by default, and two LoadOptions settings control the behaviour:
setSkipExternalResources(boolean)—trueby default; setfalseto load external resources.setWhitelistedResources(List<String>)— address fragments that are still loaded while resources are skipped. A fragment matches when the address contains it, ignoring case.
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();
}
Scope.
- Applies to Word, presentation, spreadsheet and SVG documents. Spreadsheets previously ignored the setting.
- For SVG images, external
hrefreferences, CSS@importandurl()references, external style sheet instructions and theDOCTYPEare removed before the image is read, and external entities are never read. A malformed SVG is rejected while resources are skipped. (SIGNATURENET-6001) - Documents inside an archive get the archive’s settings. (SIGNATURENET-6000)
LoadOptions.setLoadExternalResourcesis deprecated and is now the inverse ofsetSkipExternalResources, so its default changes fromtruetofalse. (SIGNATURENET-5950)
Feature — expired and not yet valid signing certificates
Signing used to accept any certificate. 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, gives the date in UTC and the property that allows it.
DigitalSignOptions options = new DigitalSignOptions("certificate.pfx");
options.setPassword("1234567890");
options.setAllowExpired(true); // sign anyway; a warning is logged
options.setAllowNotYetValid(false); // the default
Signature signature = new Signature("contract.pdf");
try {
signature.sign("contract_signed.pdf", options);
} finally {
signature.dispose();
}
Scope.
- Behaviour change: both settings are
falseby default. - Applies to digital signatures of every document type, and to the certificate of a VBA project in a spreadsheet. Images, certificate files and archives themselves are not checked; documents inside an archive are. (SIGNATURENET-5995)
Feature — OOXML compliance of Word documents
A Word document saved after signing now keeps the OOXML compliance it was loaded with (ECMA-376, Transitional or Strict). WordProcessingSaveOptions.setOoxmlCompliance sets another one:
WordProcessingSaveOptions saveOptions = new WordProcessingSaveOptions();
saveOptions.setOoxmlCompliance(OoxmlCompliance.Strict);
Signature signature = new Signature("contract.docx");
try {
signature.sign("contract_signed.docx", new TextSignOptions("John Smith"), saveOptions);
} finally {
signature.dispose();
}
The setting applies to OOXML output formats only and can be combined with a password. (SIGNATURENET-5634)
Feature — SHA-256 PDF digital signatures and HashAlgorithm
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. The time stamp, when one is requested, uses the same digest.
DigitalSignOptions options = new DigitalSignOptions("certificate.pfx");
options.setPassword("1234567890");
options.setHashAlgorithm(HashAlgorithm.Sha512); // HashAlgorithm.Auto gives SHA-256
Scope.
- Behaviour change: new PDF signatures use SHA-256 unless another algorithm is set.
- Applies to certificates given as a file, a stream or a
DigitalSignature. - Setting
HashAlgorithmon a PDF signature that is not digital has no effect, and a warning is logged. (SIGNATURENET-5976)
Feature — cryptographic verification of PDF digital signatures
Verifying a PDF with DigitalVerifyOptions compared only the criteria that were set. With no criteria, any PDF containing a signature field was reported as valid, even after the document was changed. Each signature is now verified first, and is valid only if that check passes. A signature that cannot be verified — for example a malformed one — counts as not valid instead of stopping the verification of the whole document.
The criteria that were accepted and ignored for PDF are now applied, as they already were for Word documents:
setSubjectNameandsetIssuerName— the subject or issuer of the signing certificate must contain the value (case-sensitive);setSignDateTimeFromandsetSignDateTimeTo— the signing time must lie in the window, compared in whole seconds.
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();
}
Scope.
- Behaviour change: documents that used to verify may now report not valid, when they were changed after signing or do not match these criteria. (SIGNATURENET-5978, SIGNATURENET-5997)
Feature — certificate verification
Verifying a certificate file with CertificateVerifyOptions computed nothing — every check was missing. It now applies:
setExpired(boolean)— whether the certificate’s validity period has ended, compared in UTC;setIssuer,setSubject,setSerialNumberandsetThumbprint, with the option’sMatchType. Serial number and thumbprint use the upper-case hexadecimal form of .NET;setPerformChainValidation(true)— builds a certificate path to the Java trust store. Unlike .NET, revocation is not checked.
(SIGNATURENET-6003)
Feature — public API from .NET
LoadOptions.setFileType(FileType)and theLoadOptions(FileType)constructor give the document type instead of detecting it from the content.Signature.search(Predicate<BaseSignature>)searches text, image, digital, barcode, QR-code and metadata signatures and returns those that match the predicate.VerificationResult.getFailed()is public. As in .NET it is not filled yet and stays empty.
Signature signature = new Signature(stream, new LoadOptions(FileType.PDF));
try {
List<BaseSignature> signatures = signature.search(s -> s.getPageNumber() == 1);
} finally {
signature.dispose();
}
Fix — LogLevel had no effect
The level was compared for equality instead of as a set of flags, so with the default LogLevel.All nothing was logged at all, and combined values such as LogLevel.Error | LogLevel.Warning never matched. Warnings logged with an exception also printed a literal placeholder instead of the exception message.
SignatureSettings settings = new SignatureSettings(new ConsoleLogger());
settings.setLogLevel(LogLevel.Error | LogLevel.Warning);
Signature signature = new Signature("contract.pdf", settings);
Scope.
- Behaviour change: a logger passed in
SignatureSettingsnow receives messages with the default level. SetLogLevel.Noneor a narrower level to reduce them. (SIGNATURENET-6004)
Fix — empty barcode and QR-code images on Java 11 and later
Signing presentations and spreadsheets with BarcodeSignOptions or QrCodeSignOptions 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, so the image stayed empty. Java 8 was not affected, which made the failure look specific to Linux or Docker. The image is now written as PNG, and an image that cannot be encoded raises an error instead of producing an empty one. (SIGNATUREJAVA-2903)
Fix — custom PDF signer
A custom signer set with DigitalSignOptions.setCustomSignHash was never called. The built-in ICustomSignHash implementations also hashed the digest a second time, so their signatures did not verify. The signer is now called with the digest that was actually used, and the signatures verify. (SIGNATURENET-5208)
Fix — time-stamp server credentials
Credentials were sent to the time-stamp server only when both the user name and the password were set. A server that needs only a user name, or a token in the user name, got an unauthenticated request. They are now sent when either part is set. (SIGNATURENET-5998)
Fix — reused options
- A
VerifyOptionsobject used for severalverifycalls kept the signatures of the documents verified earlier, so the result of a later call included them. Each call now starts afresh. (SIGNATURENET-6005) - A
DigitalSignOptionsobject used for several presentations signed the later ones with the first certificate and comment. (SIGNATURENET-6006)
Fix — archives
Search of an archive failed with a NullPointerException, and verification of an archive always failed because each document inside it was read as an empty stream. Both work now, and the verification result of an archive lists the signatures of all its documents.
Fix — other fixes
- Spreadsheets with a picture linked to an external file no longer fail QR-code and barcode search and verification with a
NullPointerException; such pictures are skipped. (SIGNATURENET-6002) - Certificates whose key entry has a name — most PFX files — were rejected with
certificate doesn't contain private keywhen signing presentations, spreadsheets and VBA projects. - Saving a signed document as images produced empty pages (
Unsupported file format), which also broke updating and deleting image signatures. On Java 11 and later, images with transparency found in Word documents, and presentation previews in JPEG or BMP, are no longer written empty. JpegSaveOptions,PngSaveOptions,GifSaveOptionsandTiffSaveOptionssettings such as the JPEG quality were ignored. They are applied now, and the signature information stored in the image metadata is kept.FileType.equalsreturnedtruefor any two file types, soReturnContentwas written as PNG whateverReturnContentTypewas set to.- QR-code search in multi-layer images with
ReturnContentfailed and returned no codes. - The default text of
BarcodeTypes.GS1CompositeBarused/between the linear and the 2D component, which Aspose.BarCode rejects; it now uses|. - Passing options of the wrong type, for example
ImageDigitalVerifyOptionsfor a PDF, failed withFormatException: Index (zero based) must be greater than or equal to zeroinstead of naming the expected options type.
Update — archive expansion limits
The entries of zip and tar archives were expanded without any limit, so a small archive could expand to an amount of data that exhausts memory. Archives are now checked while they are expanded: at most 10,000 entries, 1 GB in total, and no entry larger than 1 MB compressed more than 100 times. A larger archive fails with GroupDocsSignatureException, whose cause is com.groupdocs.signature.exception.ArchiveSecurityException.
Scope.
- Behaviour change: archives beyond these limits are rejected.
Update — trial limits
In evaluation mode, signing an archive is no longer limited by the number of documents in it; the page limit still applies to each document. The limit on the number of documents is checked for search, verification, preview and document information. Archives and multi-layer images were also limited to two documents with the wrong message; they now get their own limit and message. (SIGNATURENET-5825)
Update — Aspose libraries and barcode types
The Aspose libraries are updated to the versions used by GroupDocs.Total: Aspose.Words 26.8, Aspose.PDF 26.8.1, Aspose.Cells 26.9, Aspose.Slides 26.9, Aspose.BarCode 26.6, Aspose.Imaging 25.12 and others.
Aspose.BarCode merged the Standard and Extended variants of Code 39 and Code 93. BarcodeTypes.Code39, Code39FullASCII and Code93 are new, as in .NET. Code39Standard, Code39Extended, Code93Standard and Code93Extended remain as deprecated aliases, so existing code compiles and barcodes signed with the old names are still recognised. (SIGNATUREJAVA-2908)
Update — published artifact
- The manifest declares
Automatic-Module-Name: com.groupdocs.signature, so on Java 9 and later the jar resolves as a named automatic module. The copyright year is set at build time. META-INF/ThirdPartyLicenses-BouncyCastle.txtcarries the licence of the Bouncy Castle library the jar redistributes, andMETA-INF/ThirdPartyLicenses-GroupDocs.Signature.txtlists the redistributed components.- The jar is no longer signed with
jarsigner, whose certificate had expired. Detached PGP signatures (.asc) of the jar, the POM and the javadoc jar are published next to them. - The public fields
MeCard.auto_Nameand theSignaturesandActionsfields ofDocumentMetaInfoContextare private; useMeCard.getName()andsetName().
(SIGNATUREJAVA-2905)
Update — POM metadata and distribution links
The published POM carries the product name GroupDocs.Signature for Java, a short description, and declares <licenses>, <developers>, <organization> and <scm>. This is what dependency indexes such as MVNRepository display. The license agreement in the distribution package now opens the GroupDocs License Agreement, and the product page, documentation and examples links in readme.txt and the package shortcuts were updated the same way. Metadata and package contents only — no code, behaviour or API changed. (SIGNATUREJAVA-2906, SIGNATUREJAVA-2925)