TX Text Control .NET for Windows Forms

Timestamp Configuration

Topic

Why would a signature need a clock? Because years later, when the signer's certificate has expired, a reader of the document wants to know whether the certificate was valid at the moment of signing. The clock of the signing computer can't prove that: anybody can change it. A trusted timestamp from an RFC 3161 time server can. In a Windows Forms application, you configure it with a single parameter, the address of the time server, and TX Text Control requests the timestamp while it saves the signed PDF.

The shortest version, a timestamp for a whole-document signature, is part of Add a Trusted Timestamp in Getting Started. The sections below add what an application needs around it: fallback servers, a decision when no server answers and timestamps for signature fields.

Why a Signature Needs a Trusted Time

Suppose a contract is signed in February 2026 with a certificate that expires in January 2027, and somebody opens the contract in 2032. By then, a PDF reader knows only that the certificate has expired, not whether it was valid in February 2026. Without a trusted time, Adobe Acrobat and other validators often show warnings or state that the long-term validity of the signature can't be verified, although the document is unchanged.

With a trusted timestamp, the validator can confirm that the signature matches the document, that the timestamp is trusted, that the certificate was valid at the time of the timestamp and that the document hasn't changed since:

A timeline with a certificate issued in January 2026, expiring in January 2027 and a document opened in 2032, next to the checks a validator passes thanks to the timestamp.

How a Timestamp Is Created

A time server, also called a Time-Stamping Authority (TSA), doesn't sign your document. When TX Text Control saves a signed PDF with a time server URL, these steps happen:

  1. TX Text Control creates the signature of the document.
  2. It sends a cryptographic hash of the signature to the time server. The PDF itself never leaves the computer.
  3. The time server combines the hash with the current, trusted UTC time and signs the result with its own certificate.
  4. TX Text Control embeds the returned timestamp token in the PDF as part of the signature.

For a desktop application, this means that the computer that signs needs a network connection to the time server at the moment of saving. The time server has no access to the document or its content.

Specify the Time Server

Both constructors of DigitalSignature take the URL of the time server as their second parameter, timeServerURL:

Value of timeServerURLSigning time
An empty stringThe current date and time of the computer
The URL of an RFC 3161 time server, such as http://timestamp.digicert.comA trusted timestamp from the time server

Timestamps are offered by certificate authorities, and many organizations operate their own time servers for internal signing. Use a server that the readers of your documents trust, because validators check the timestamp as well.

DigitalSignature has no further settings for the time server, such as credentials, a proxy or a timeout. The server is contacted when Save creates the PDF, not when the DigitalSignature object is created.

Handle an Unavailable Time Server

When the time server doesn't exist or returns invalid data, Save throws a FilterException whose Reason is InvalidTimeServer. The following handler tries the time servers of a list in order. If none of them answers, for example because the computer is offline, it asks the user whether to sign with the date and time of the computer instead. Form1.cs needs using System.Security.Cryptography.X509Certificates; and using TXTextControl;.

private readonly string[] timeServers =
{
    "http://timestamp.digicert.com",
    // Add the URL of a second RFC 3161 time server, for example your organization's own
};

private void signWithTimestampButton_Click(object sender, EventArgs e)
{
    X509Certificate2 certificate = X509CertificateLoader.LoadPkcs12FromFile(
        "certificate.pfx", "123", X509KeyStorageFlags.Exportable);

    byte[] signedPdf = null;

    foreach (string timeServer in timeServers)
    {
        SaveSettings saveSettings = new SaveSettings()
        {
            DigitalSignature = new DigitalSignature(certificate, timeServer)
        };

        try
        {
            textControl1.Save(out byte[] pdf, BinaryStreamType.AdobePDF, saveSettings);
            signedPdf = pdf;
            break;
        }
        catch (FilterException exception) when (exception.Reason == FilterException.FilterError.InvalidTimeServer)
        {
            // Try the next time server
        }
    }

    if (signedPdf == null)
    {
        DialogResult answer = MessageBox.Show(this,
            "No time server returned a timestamp. Sign with the date and time of this computer instead?",
            "Timestamp", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

        if (answer != DialogResult.Yes)
        {
            return;
        }

        SaveSettings saveSettings = new SaveSettings()
        {
            DigitalSignature = new DigitalSignature(certificate, "")
        };

        textControl1.Save(out signedPdf, BinaryStreamType.AdobePDF, saveSettings);
    }

    File.WriteAllBytes("signed.pdf", signedPdf);
}

The code works as follows:

  • Each attempt creates a new SaveSettings object with a DigitalSignature for the next time server.
  • The document is saved into a byte array, and the file is written only after a signature was created.
  • Without an answer from any time server, the user decides. For documents that must stay verifiable for years, leave out the question and don't sign without a timestamp: the document shouldn't silently lose it.

Add Timestamps to Signature Fields

When signature fields are signed, each field gets its own DigitalSignature in SaveSettings.SignatureFields, and each of them has its own time server URL. To give every field a trusted timestamp, pass the URL instead of the empty string in the handler of Sign the Fields of the Document:

signatures.Add(new DigitalSignature(certificate, "http://timestamp.digicert.com", field.Name));

Each field then gets a timestamp of its own. Fields of one document can use different time servers, or none: Multiple Signatures signs one field with a timestamp and two without. The same InvalidTimeServer handling as above applies.

How Readers Show the Signing Time

Adobe Acrobat Reader lists each signature in its Signatures panel. For a signature without a timestamp, the panel says that the signing time is from the clock on the signer's computer:

Adobe Acrobat with the Signatures panel open, stating among the details of a valid signature that the signing time is from the clock on the signer's computer.

With a timestamp, the time is part of the signature as cryptographic evidence, so the signature can still be verified after the certificate has expired. The blog article Building Long-Term Trust with Digital Signatures and Timestamps in C# .NET explains the validation in more detail.

Timestamps and PAdES

Archives, contracts and regulations often ask for signatures by their PAdES profile, the PDF Advanced Electronic Signature profiles. Two of them differ only in the timestamp:

PAdES-BPAdES-T
ContainsThe digital signature, the signer's certificate and its certificate chainEverything in PAdES-B and a trusted RFC 3161 timestamp
After the certificate expires or is revokedA validator may not be able to tell whether the certificate was valid at signing timeThe timestamp proves that the signature existed while the certificate was valid

According to Text Control, a signature that TX Text Control creates with a certificate and the URL of a time server conforms to PAdES-T. The time server URL is the only choice you make: DigitalSignature has no members besides its constructors, so there is no setting for a profile, a hash algorithm or revocation data. When a recipient or a regulation requires a particular level, sign sample documents and check them with the validator the recipient uses before you rely on them. Verify the Signatures in Code shows what the TXTextControl.PDF.Validation package checks.

Next Steps