PDF Generation Template Editor
Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.
Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.
For SDK requirements and common imports, see Digital Signatures.
Long-term validation preserves certificate and revocation evidence needed to validate a signature later. The Java SDK provides PAdES creation, LTV prolongation, material assessment, and detailed validation reports.
| Profile | Content | Output |
|---|---|---|
| B | Baseline signature with a signing-certificate reference | Signed PDF |
| T | B plus an embedded RFC 3161 signature timestamp | Signed PDF |
| LT | T plus certificate and revocation evidence in DSS/VRI | LTV PDF |
| LTA | LT plus an archival document timestamp protecting the evidence | LTA PDF |
Initialize the SDK before calling these APIs. Signing, evidence collection, and TSA requests are synchronous, so run them on a worker thread. Save document edits first and keep the input file unchanged during the operation.
Each requested output must use a distinct new path in an existing directory. These high-level entry points do not accept a PDF-open password. The PKCS#12 password unlocks the signing certificate container, not the PDF.
Create a PAdES-LT Signature
The following example creates an invisible PAdES-LT signature. Replace the certificate, trust bundle, TSA endpoint, and CRL URL with resources appropriate to your signing identity.
Files.createDirectories(Paths.get("output"));
CPDFSignatureValidationOptions validation = new CPDFSignatureValidationOptions()
.setTrustedCertPath("certs/trusted-roots.pem")
.setCheckRevocation(true);
CPDFPadesOptions options = new CPDFPadesOptions()
.setProfile(CPDFPadesOptions.Profile.LT)
.setCertificate("certs/signer.p12", "YOUR_PKCS12_PASSWORD")
.setFieldName("PadesSignature")
.setVisible(false)
.setTsaUrl("https://tsa.example.com/timestamp")
.setTsaTransport(20, 0, "")
.setTrustedCertPath("certs/trusted-roots.pem")
.setRevocationUrls(null, new String[] {"https://ca.example.com/issuer.crl"})
.setValidationOptions(validation);
CPDFPadesResult result = CPDFPadesSigner.sign(
"input.pdf",
"output/pades-signed.pdf",
"output/pades-lt.pdf",
null,
options);
System.out.println("Process success: " + result.isSuccess());
System.out.println("Target profile satisfied: " + result.isTargetProfileSatisfied());
System.out.println("Final completed output: " + result.getFinalPath());
System.out.println(Arrays.toString(result.getErrors()));
System.out.println(result.getValidationResult());For LTA creation, select Profile.LTA and supply a new LTA output path as the fourth argument to sign(). Configure an archival TSA through setLtaTsaUrl() when it differs from the signature TSA.
The trust bundle must contain the trust anchors required for the signer and TSA chains. Certificates embedded in a PDF or CMS container do not become trusted merely because they are embedded.
Prolong LTV for an Existing Signature
Use prolongLtv() to collect or update evidence for an existing signed PDF. It does not create another approval signature or require a new PKCS#12 signer. The existing signature must be suitable for the requested profile; adding evidence does not rebuild its signed attributes.
Files.createDirectories(Paths.get("output"));
CPDFPadesOptions options = new CPDFPadesOptions()
.setTrustedCertPath("certs/trusted-roots.pem")
.setRevocationUrls(null, new String[] {"https://ca.example.com/issuer.crl"})
.setTsaUrl("https://tsa.example.com/timestamp")
.setTsaTransport(20, 0, "")
.setAppendDocumentTimestamp(true);
CPDFPadesResult result = CPDFPadesSigner.prolongLtv(
"existing-pades-t.pdf",
"output/prolonged-lt.pdf",
"output/prolonged-lta.pdf",
options);
System.out.println("Process success: " + result.isSuccess());
System.out.println("Target profile satisfied: " + result.isTargetProfileSatisfied());
System.out.println(result.getValidationResult());Set appendDocumentTimestamp to false and omit the LTA path when only extending LT evidence. If a later stage fails, an earlier successfully completed stage may remain available. Inspect the error list and actual completed paths rather than treating every configured output path as a successful output.
Assess Embedded Materials
CPDFLtvService.assessReadiness() reports material availability. It does not establish certificate trust, revocation validity, or a verified PAdES profile.
CPDFDocument document = new CPDFDocument();
try {
document.open("output/pades-lt.pdf");
CPDFLtvReadinessResult result = CPDFLtvService.assessReadiness(document);
if (result != null && result.isSuccess()) {
System.out.println("LTV materials ready: "
+ result.getReadinessInfo().isLtvReady());
}
} finally {
document.close();
}Read Detailed Validation Reports
Use CPDFSignatureValidator to inspect the exact saved PDF bytes. Validation reads embedded evidence; it does not collect new OCSP/CRL material. Enable revocation checks for an LTV verdict and configure native trust anchors explicitly.
CPDFSignatureValidationOptions options = new CPDFSignatureValidationOptions()
.setTrustedCertPath("certs/trusted-roots.pem")
.setCheckRevocation(true);
CPDFSignatureValidationResult result = CPDFSignatureValidator.validate(
"output/pades-lt.pdf", options);
System.out.println("Overall status: " + result.getOverallStatus());
for (CPDFSignatureValidationReport report : result.getReports()) {
System.out.println("Field: " + report.getFieldName());
System.out.println("SubFilter: " + report.getSubFilter());
System.out.println("Status: " + report.getOverallStatus());
System.out.println("LTV enabled: " + report.isLtvEnabled());
for (CPDFValidationReportItem item : report.getItems()) {
System.out.println(item);
}
}Process success, material readiness, target-profile satisfaction, and complete validation are separate results. isTargetProfileSatisfied() is a profile helper; for LTA, inspect the document timestamp reports as well. Strict acceptance should require the target evidence and valid reports for all signatures and timestamps relevant to the application.
The statuses INVALID, INDETERMINATE, and NOT_CHECKED have different meanings. A signature can have valid cryptographic integrity while other checks remain indeterminate, including missing LTV evidence. The SDK does not convert that state to VALID.
See SignatureLtvKmsTest for a complete LT creation and prolongation example.