# Digitally Sign a PDF

> Sign PDF files from Windows Forms with a .pfx certificate and DigitalSignature: invisible signatures, trusted timestamps and a signature field with an image.

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

---

A digital signature proves who signed a PDF and that nobody changed it afterward. TX Text Control signs a document while it saves it as PDF, with a certificate from a *.pfx* file. The steps below create a test certificate, sign the whole document of the editor, add a trusted timestamp, and sign a visible signature field with an image.

### How PDF Signing Works

You pass a [DigitalSignature](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/digitalsignature/llms-full.txt) to the `SaveSettings` of a PDF or PDF/A save. It contains an X.509 certificate with its private key, and TX Text Control signs the document with it. There are two ways:

- **Sign the whole document.** [SaveSettings.DigitalSignature](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/digitalsignature-property/llms-full.txt) signs the document invisibly. The PDF reader shows the signature in its signature panel.
- **Sign signature fields.** A [SignatureField](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/signaturefield/llms-full.txt) is a visible frame in the document, for example with an image of a handwritten signature. [SaveSettings.SignatureFields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/signaturefields-property/llms-full.txt) signs named fields, one certificate per field, which also allows several signers.

### Prerequisites

- The application from [Create Your First Windows Forms Application](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/document-editor/first-application/llms-full.txt), with a `TextControl` named `textControl1` on `Form1`.
- A certificate with its private key as a *.pfx* file. For testing, create one as shown below.

*Form1.cs* needs these `using` directives:

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

### Create a Self-Signed Certificate for Testing

A self-signed certificate is enough for testing and internal use. Because no trusted certificate authority issued it, use a certificate from a certificate authority for documents that other people must be able to trust.

In PowerShell on Windows, create the certificate in your 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)
```

Then export it with its private key and the password `123` to a *.pfx* file:

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

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

Copy *certificate.pfx* into the output folder of your application, or use its full path in the code below.

### Sign the Whole Document

Add a button named `signPdfButton` and double-click it:

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

    SaveSettings saveSettings = new SaveSettings()
    {
        // An empty string uses the computer's date and time
        DigitalSignature = new DigitalSignature(certificate, "")
    };

    string path = 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` loads the certificate and its private key from the *.pfx* file. It is available in .NET 9 and higher. In .NET 8 and in the .NET Framework, use the constructor instead: `new X509Certificate2("certificate.pfx", "123", X509KeyStorageFlags.Exportable)`.
- The [DigitalSignature constructor](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/digitalsignature/constructor/llms-full.txt) takes the certificate and the URL of a timestamp server. With an empty string, the signature carries the date and time of the computer.
- [Save](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/save-method/llms-full.txt) signs the document while it writes the PDF. The same works with `StreamType.AdobePDFA`.

Run the application and click the button. The PDF reader shows 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-winforms/signature-panel-invisible.62a2f499.webp)

### Add a Trusted Timestamp

The date and time of the computer can be changed by anyone. A timestamp server confirms the time of signing independently: TX Text Control sends only a hash of the signature to the server and embeds the server's timestamp in the PDF. In `signPdfButton_Click`, pass the URL of an RFC 3161 timestamp server instead of the empty string:

```csharp
SaveSettings saveSettings = new SaveSettings()
{
    // Request a timestamp from a timestamp server
    DigitalSignature = new DigitalSignature(certificate, "http://timestamp.digicert.com")
};
```

### Sign a Signature Field

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

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

    // A field of 3000 x 1500 twips, named "txsign"
    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-winforms/reference/txtextcontrol/signaturefield/constructor/llms-full.txt) takes the size of the field in twips, its name and an ID. A field needs a name so that a certificate can be assigned to it.
- [SignatureImage](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/signatureimage/constructor/llms-full.txt) loads the image the field shows. The second parameter is the image format: 1 BMP, 2 TIF, 3 WMF, 4 PNG, 5 JPG, 6 GIF, 7 EMF or 8 SVG.
- [SignerData](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/signerdata/constructor/llms-full.txt) describes the signer: name, title, address, contact information and the reason for signing.
- [SignatureFields.Add](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/signaturefieldcollection/add-method/llms-full.txt) inserts the field into the document.
- The third parameter of `DigitalSignature` names the field it signs. For several signers, pass one `DigitalSignature` per 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-winforms/signature-field-validated.b43f5137.webp)

### Next Steps

- [Digital Signatures](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/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-winforms/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-winforms/getting-started/pdf/form/llms-full.txt)
- **Next:** [Document Editor](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/llms-full.txt)
