# Digitally Sign a PDF

> Sign a PDF from a WPF TextControl with an X.509 certificate: create a test .pfx, sign signature fields and understand timestamp limitations.

- **Product:** TX Text Control .NET for WPF
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for WPF > Getting Started > PDF Processing > Digitally Sign a PDF
- **2866 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/pdf/sign/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/pdf/sign/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/pdf/sign/llms-full.txt

---

With a digital signature, the reader of a PDF can verify who signed it and that it has not been changed since. TX Text Control signs a PDF while saving it, with an X.509 certificate from a *.pfx* file. In the editor window of your first WPF application, you create a certificate for testing, sign the document invisibly and sign a visible signature field that shows an image of a handwritten signature. The timestamp section explains a limitation in version 34.0 SP5.

### How PDF Signing Works

A [DigitalSignature](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/digitalsignature/llms-full.txt) holds an X.509 certificate with its private key. Passed in the `SaveSettings` of a PDF or PDF/A save, it makes TX Text Control sign the file, in one of two ways:

- **The whole document.** [SaveSettings.DigitalSignature](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/savesettings/digitalsignature-property/llms-full.txt) signs the document without a visible mark. PDF readers list the signature in their signature panel.
- **Signature fields.** A [SignatureField](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/signaturefield/llms-full.txt) is a visible frame in the document, which can show an image and information about the signer. [SaveSettings.SignatureFields](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/savesettings/signaturefields-property/llms-full.txt) signs fields by name, each with its own certificate, so several people can sign one document.

### Prerequisites

- The application from [Create Your First WPF Application](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/document-editor/first-application/llms-full.txt), with a `TextControl` named `textControl1` in *MainWindow.xaml*.
- A certificate with its private key in a *.pfx* file. The next section creates one for testing.
- For the signature field, an image of a signature named *signature.png* in the output folder of the application.

*MainWindow.xaml.cs* needs these `using` directives:

```csharp
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Windows;
using TXTextControl;
```

### Create a Self-Signed Certificate for Testing

A self-signed certificate works for tests and internal documents. No trusted certificate authority has issued it, so PDF readers of other people don't trust it. For documents that others must be able to verify, use a certificate from a certificate authority.

In PowerShell on Windows, the following command creates a certificate in your personal certificate store:

```powershell
$cert = New-SelfSignedCertificate `
  -Subject "CN=MyTXCert" `
  -CertStoreLocation "Cert:\CurrentUser\My" `
  -KeyExportPolicy Exportable `
  -KeySpec Signature `
  -FriendlyName "My PDF Signing Certificate" `
  -NotAfter (Get-Date).AddYears(5)
```

The next commands export it with its private key to a *.pfx* file protected by the password `123`:

```powershell
$Password = ConvertTo-SecureString -String "123" -Force -AsPlainText

Export-PfxCertificate `
    -Cert "Cert:\CurrentUser\My\$($cert.Thumbprint)" `
    -FilePath "C:\Path\To\certificate.pfx" `
    -Password $Password
```

Add *certificate.pfx* to the project with **Copy to Output Directory** set to **Copy if newer**, or use its full path in the code below.

### Sign the Whole Document

Add a button named `signPdfButton` to the `DockPanel` of *MainWindow.xaml*, before the `TextControl` element, and this handler to *MainWindow.xaml.cs*:

```csharp
private void signPdfButton_Click(object sender, RoutedEventArgs e)
{
    // Load the certificate with its private key
    X509Certificate2 certificate = X509CertificateLoader.LoadPkcs12FromFile(
        "certificate.pfx", "123", X509KeyStorageFlags.Exportable);

    SaveSettings saveSettings = new SaveSettings()
    {
        // An empty string signs with the date and time of the computer
        DigitalSignature = new DigitalSignature(certificate, "")
    };

    string path = System.IO.Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
        "signed.pdf");

    textControl1.Save(path, StreamType.AdobePDF, saveSettings);

    Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
}
```

The code works as follows:

- `X509CertificateLoader.LoadPkcs12FromFile` reads the certificate and its private key from the *.pfx* file. The class exists from .NET 9 on. A project for .NET 8 or the .NET Framework uses the constructor instead: `new X509Certificate2("certificate.pfx", "123", X509KeyStorageFlags.Exportable)`.
- The [DigitalSignature constructor](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/digitalsignature/constructor/llms-full.txt) takes the certificate and the URL of a timestamp server. An empty string uses the current date and time of the computer.
- [Save](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/save-method/llms-full.txt) signs the document as it writes the PDF. `StreamType.AdobePDFA` works the same way.

Run the application and click the button. The PDF reader opens *signed.pdf* and lists the signature in its signature panel, as an invisible signature:

![Adobe Acrobat with the Signatures panel open, showing a valid signature of an invisible signature field.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/signature-panel-invisible.62a2f499.webp)

### Add a Trusted Timestamp

Anyone can change the clock of a computer. A timestamp server, also called a time-stamping authority, confirms the time of signing independently: it receives a hash of the signature, not the document, and returns a signed timestamp that is embedded in the PDF.

> Warning
>
> **Timestamp Servers in Version 34.0 SP5.** Requesting a server timestamp can fail during PDF export with a `FilterException` (TXT-5460). Keep the timestamp-server parameter empty for this tutorial. Before enabling server timestamps, verify that your installed build resolves TXT-5460.

Keep `new DigitalSignature(certificate, "")` in `signPdfButton_Click`. It signs with the computer's current date and time and does not provide a trusted timestamp or independent proof of the signing time.

### Sign a Signature Field

A signature field shows on the page where the document is signed and by whom. The following handler inserts a field with an image at the input position and signs it while saving:

```csharp
private void signFieldButton_Click(object sender, RoutedEventArgs e)
{
    X509Certificate2 certificate = X509CertificateLoader.LoadPkcs12FromFile(
        "certificate.pfx", "123", X509KeyStorageFlags.Exportable);

    // A field of 3000 x 1500 twips named "txsign", with the ID 10
    SignatureField signatureField = new SignatureField(
        new System.Drawing.Size(3000, 1500), "txsign", 10);

    // The image of the signature. Filter index 4 is PNG.
    signatureField.Image = new SignatureImage("signature.png", 4);
    signatureField.SignerData = new SignerData(
        "Tim Typer", "CEO", "Charlotte, NC", "tim@example.com", "Approval");

    // -1 inserts the field at the current input position
    textControl1.SignatureFields.Add(signatureField, -1);

    SaveSettings saveSettings = new SaveSettings()
    {
        // Sign the field named "txsign"
        SignatureFields = new DigitalSignature[]
        {
            new DigitalSignature(certificate, "", "txsign")
        }
    };

    textControl1.Save("signed-field.pdf", StreamType.AdobePDF, saveSettings);
}
```

The code works as follows:

- The [SignatureField constructor](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/signaturefield/constructor/llms-full.txt) takes the size in twips as a `System.Drawing.Size`, not a WPF `Size`, then the name and an ID. The name is required when a certificate is assigned to the field.
- The [SignatureImage constructor](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/signatureimage/constructor/llms-full.txt) loads the image the field shows. Its second argument is the image format: 1 BMP, 2 TIF, 3 WMF, 4 PNG, 5 JPG, 6 GIF, 7 EMF or 8 SVG.
- The [SignerData constructor](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/signerdata/constructor/llms-full.txt) takes the name, title, address and contact information of the signer and the reason for signing.
- [SignatureFields.Add](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/signaturefieldcollection/add-method/llms-full.txt) inserts the field into the document of the editor.
- The third argument of `DigitalSignature` names the field to sign. For several signers, pass one `DigitalSignature` for each field.

In a PDF reader, the field shows the image, and the signature panel names the field *txsign*:

![Adobe Acrobat showing a signed signature field with a handwritten signature and the validation status of the signature of the field txsign.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/signature-field-validated.b43f5137.webp)

### Next Steps

- [Digital Signatures](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/digital-signatures/llms-full.txt): certificates, signature fields, multiple signatures and timestamps in detail.
- [Create a PDF](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/pdf/create/llms-full.txt): document properties, PDF/A and passwords.
- The blog article [Signing a PDF Document vs. Signing Signature Fields in a PDF in C#](https://www.textcontrol.com/blog/2024/10/08/signing-a-pdf-document-vs-signing-signature-fields-in-a-pdf-in-csharp/): when to use which way.
- The blog article [Building Long-Term Trust with Digital Signatures and Timestamps in C# .NET](https://www.textcontrol.com/blog/2026/08/04/building-long-term-trust-with-digital-signatures-and-timestamps-in-c-sharp-dot-net/): why timestamps matter.

---

## Nearby

- **Previous:** [Create a PDF Form](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/pdf/form/llms-full.txt)
- **Next:** [Document Editor](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/llms-full.txt)
