PAdES-B-LTA (long-term archival, ETSI EN 319 142) is the format recommended to keep a signed PDF document valid for many years. The document gets a time-stamped signature, the validation data of the signing certificate (the certificate chain and the CRL and OCSP responses, in the Document Security Store) and a document time-stamp that protects the whole document and its validation data. Before the certificate of the time-stamping authority expires, a new document time-stamp extends the protection, again and again, for the whole archival time.
How to create a PAdES-LTA signature in C#
- Set
SignatureStandard = PdfSignatureStandard.PadesLTAon aPdfSignatureobject. - Choose the revocation data with
PadesLtvLevel:IncludeCrlAndOcsp,IncludeOcspOnly(smaller files),IncludeCrlorNone. - Set a time-stamping server in
TimeStamping.ServerUrl: it time-stamps the signature and the document. - Sign with
ApplyDigitalSignature. The validation data is collected from the CRL and OCSP addresses written in the certificates. - Periodically, check the certificate of the time-stamping authority of the last document time-stamp and add a new document time-stamp with
ApplyTimestampSignature. The signing certificate is not needed, and the previous signatures and time-stamps remain valid.
C# code: sign a PDF with PAdES-B-LTA
/// <summary>
/// Signs a PDF file with a PAdES-LTA signature: signature, validation data and document time-stamp.
/// </summary>
static void SignPdfWithPadesLongTermArchival(string unsignedPdfFile, string signedPdfFile)
{
PdfSignature pdfSignature = new PdfSignature(LibrarySerialNumber);
pdfSignature.LoadPdfDocument(unsignedPdfFile);
pdfSignature.DigitalSignatureCertificate = LoadSigningCertificate();
pdfSignature.SigningReason = "I approve this document";
pdfSignature.SigningLocation = "Accounting department";
pdfSignature.SignaturePosition = SignaturePosition.TopLeft;
pdfSignature.HashAlgorithm = SignLib.HashAlgorithm.SHA256;
// PAdES-B-LTA: PAdES-B-LT (the validation data is added to the document security store) followed by a
// document time-stamp (an invisible time-stamp signature) of the whole document.
pdfSignature.SignatureStandard = PdfSignatureStandard.PadesLTA;
// The revocation information collected from the certification authority and embedded in the document:
// IncludeCrlAndOcsp - the CRLs and the OCSP responses; IncludeOcspOnly - the OCSP responses (smaller files)
// and the CRLs only when an OCSP response is not available; IncludeCrl - the CRLs only; None - no revocation data.
pdfSignature.PadesLtvLevel = PadesLtvLevel.IncludeCrlAndOcsp;
// A time-stamping server is required: it time-stamps the signature and the document.
pdfSignature.TimeStamping.ServerUrl = TimestampServerUrl;
pdfSignature.TimeStamping.HashAlgorithm = SignLib.HashAlgorithm.SHA256;
File.WriteAllBytes(signedPdfFile, pdfSignature.ApplyDigitalSignature());
Console.WriteLine("The PDF signature was created." + Environment.NewLine);
}
C# code: renew the document time-stamp of an archive
The first method decides whether a document must be renewed: the certificate of the time-stamping authority of its last document time-stamp expires soon. The second one adds the new document time-stamp over the whole document.
/// <summary>
/// Checks if the archived document must be renewed: the certificate of the TSA that signed the last document time-stamp expires soon.
/// </summary>
static bool IsRenewalNeeded(string signedPdfFile)
{
PdfSignature pdfSignature = new PdfSignature(LibrarySerialNumber);
pdfSignature.LoadPdfDocument(signedPdfFile);
X509Certificate2 lastTsaCertificate = null;
foreach (PdfSignatureInfo signatureInfo in pdfSignature.DocumentProperties.DigitalSignatures)
{
if (signatureInfo.SignatureType == SignatureType.TimestampSignature)
lastTsaCertificate = signatureInfo.SignatureCertificate;
}
if (lastTsaCertificate == null)
return true;
Console.WriteLine("The certificate of the TSA of the last time-stamp expires on " + lastTsaCertificate.NotAfter.ToShortDateString() + ".");
return lastTsaCertificate.NotAfter - DateTime.Now < RenewalMargin;
}
/// <summary>
/// Adds a new document time-stamp to a signed PDF file. It covers the whole document, including the validation data and the previous
/// time-stamps. The operation can be repeated for the whole archival time.
/// </summary>
static void RenewDocumentTimestamp(string signedPdfFile, string renewedPdfFile)
{
PdfSignature pdfSignature = new PdfSignature(LibrarySerialNumber);
pdfSignature.LoadPdfDocument(signedPdfFile);
// No signing certificate is needed: only the time-stamping server.
pdfSignature.TimeStamping.ServerUrl = TimestampServerUrl;
pdfSignature.TimeStamping.HashAlgorithm = SignLib.HashAlgorithm.SHA256;
File.WriteAllBytes(renewedPdfFile, pdfSignature.ApplyTimestampSignature());
Console.WriteLine("The document time-stamp was renewed." + Environment.NewLine);
}
Run the renewal as a scheduled task over the whole archive. The project Timestamp Renewal PDF ASiC XAdES of the download renews the PDF, ASiC-E and XAdES archives together. The same long-term archival exists for XAdES-LTA, CAdES-LTA and ASiC-E containers; without the document time-stamp, the signature is PAdES-LTV (PAdES-B-LT).
The free server of the sample is for tests. For signatures with legal effect in the European Union, use a qualified time-stamping service, such as the eIDAS qualified timestamps of qtsa.eu; to run your own server, see TSA Server.
PAdES-LTA from PowerShell
The scripts signPdfPadesLTA.ps1 and renewPdfTimestamp.ps1 of the folder PowerShell Scripts do the same from Windows PowerShell 5.1:
powershell -ExecutionPolicy Bypass -File signPdfPadesLTA.ps1 contract.pdf contract[lta].pdf -TimestampUrl https://tsa.example.com/tsr -LtvLevel IncludeCrlAndOcsp
powershell -ExecutionPolicy Bypass -File renewPdfTimestamp.ps1 archive.pdf archive.pdf -OnlyIfNeeded -MarginDays 730
Run the full sample. The complete Visual Studio project PDF Digital Signature Long-Term Archival PAdES-LTA is included in the library download, in the folder NET Sample Projects (.NET 8, .NET 9 and .NET 10) and in NET Framework Sample Projects (.NET Framework 4.6.2), with the test files and a test certificate. Without a serial number the library runs in demo mode. Download the library and the samples · User manual
Frequently asked questions
What is the difference between PAdES-LTV and PAdES-LTA?
PAdES-LTV (PAdES-B-LT) contains the time-stamp and the validation data of the signature. PAdES-LTA adds a document time-stamp that protects them and that can be renewed, so the document can be validated for decades.
How often must a PAdES-LTA document be renewed?
Before the certificate of the time-stamping authority of the last document time-stamp expires, or earlier if its algorithms are no longer considered secure. The sample checks the expiry date and renews only when it is needed.
Does Adobe Reader recognize PAdES-LTA documents?
Yes. The signature and the document time-stamps are standard PDF signatures; Adobe Reader shows the signature as LTV enabled when the certificates and the time-stamps are trusted and the revocation information is embedded.
Why is there no revocation data in my document?
The validation data is taken from the CRL and OCSP addresses of the certificates. A self-signed test certificate has none, so only the certificate is stored in the document.