# Multiple Signatures

> Sign one PDF for several people in Windows Forms: one DigitalSignature per signature field, different certificates, sequential signers and a final save.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > Digital Signatures > Multiple Signatures
- **2789 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/multiple/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/multiple/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/multiple/llms-full.txt

---

When a discloser and a vendor both sign an agreement, each signature must be recognizable and verifiable on its own. Signature fields make that possible: every named field gets its own certificate, its own timestamp and its own entry in the signature panel of a PDF reader. With TX Text Control, all of these signatures are applied in one save, at the end of the process, after every party has put their signature into the document.

The API of signature fields, their images and their signer data are described in [Signature Fields and Signature Appearance](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/signature-fields/llms-full.txt). The examples below use an agreement with three named signature fields, `sign_discloser`, `sign_vendor` and `init_vendor`, inserted as [Signature Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/signature-fields/llms-full.txt) in Document Editor describes.

### How Several Signatures Are Written

- **One `DigitalSignature` per field.** [SaveSettings.SignatureFields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/signaturefields-property/llms-full.txt) takes an array of [DigitalSignature](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/digitalsignature/llms-full.txt) objects. Each one names a field and has its own certificate and its own time server URL, so fields can be signed with different certificates, and only some of them with a trusted timestamp.
- **One save writes them all.** The certificates are applied while the PDF is created. Signatures are created only when TX Text Control saves a document as PDF; a PDF that it loads is converted into an editable document, as [PDF Import and Its Limitations](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/import/llms-full.txt) explains. So a document collects the signature images of its signers in an editable format and becomes a signed PDF in the last step.
- **Each signature is listed on its own.** PDF readers show every signature with the name of its field and its own validation status.
- **Signature fields, not a whole-document signature.** `SaveSettings.DigitalSignature` signs the document once, with one certificate. For several signatures, use signature fields.

### Sign Several Fields in One Save

The following handler signs the three fields of the agreement in the editor with two certificates: the discloser's field with a trusted timestamp, and the vendor's signature and initials with the date and time of the computer. *Form1.cs* needs `using System.Security.Cryptography.X509Certificates;` and `using TXTextControl;`.

```csharp
private void signAgreementButton_Click(object sender, EventArgs e)
{
    // The discloser's and the vendor's certificates
    X509Certificate2 discloserCertificate = X509CertificateLoader.LoadPkcs12FromFile(
        "certificate.pfx", "123", X509KeyStorageFlags.Exportable);
    X509Certificate2 vendorCertificate = X509CertificateLoader.LoadPkcs12FromFile(
        "vendor.pfx", "123", X509KeyStorageFlags.Exportable);

    string[] names = { "sign_discloser", "sign_vendor", "init_vendor" };

    foreach (string name in names)
    {
        SignatureField field = textControl1.SignatureFields.GetItem(name);

        if (field == null)
        {
            MessageBox.Show(this, $"The document has no signature field named {name}.");
            return;
        }

        // The image shown in the field (filter index 4 is PNG)
        field.Image = new SignatureImage($"{name}.png", 4);
    }

    SaveSettings saveSettings = new SaveSettings()
    {
        SignatureFields = new DigitalSignature[]
        {
            // With a trusted timestamp
            new DigitalSignature(discloserCertificate, "http://timestamp.digicert.com", "sign_discloser"),

            // With the date and time of this computer
            new DigitalSignature(vendorCertificate, "", "sign_vendor"),
            new DigitalSignature(vendorCertificate, "", "init_vendor")
        }
    };

    textControl1.Save("nda-signed.pdf", StreamType.AdobePDFA, saveSettings);
}
```

The code works as follows:

- *vendor.pfx* is a second test certificate, created like *certificate.pfx* in [Create a Self-Signed Certificate for Testing](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/pdf/sign/#create-a-self-signed-certificate-for-testing). Every certificate needs its private key on the computer that signs.
- [SignatureFieldCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/signaturefieldcollection/getitem-method/llms-full.txt) makes sure the document contains each field before it's signed, and [SignatureField.Image](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/signaturefield/image-property/llms-full.txt) sets its image, here from PNG files named after the fields.
- The third parameter of each `DigitalSignature` names its field, and the second is the URL of the time server or an empty string.
- One `Save` call writes the PDF/A document with all three signatures.

`X509CertificateLoader` requires .NET 9 or higher; [Load the Certificate From a PFX File](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/certificates/#load-the-certificate-from-a-pfx-file) shows the alternative for .NET 8 and the .NET Framework.

### Collect Signatures From Several People

In many processes, the parties sign one after the other, each on their own computer with the same Windows Forms application, and the organization certifies the document at the end:

1. **Prepare the document** with one named field per signer, including the signer data, and save it in the TX Text Control format, for example as *nda.tx*.
2. **Each signer opens the document**, adds the image of their signature to their field, as [Add a Signature Image](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/signature-fields/#add-a-signature-image) shows, and saves the document again in the TX Text Control format:

```csharp
private void saveForNextSignerButton_Click(object sender, EventArgs e)
{
    // Keep the signatures of this signer in the TX Text Control format
    textControl1.Save("nda.tx", StreamType.InternalUnicodeFormat);
}
```

1. **The last step certifies the document**: it checks that every field has an image and signs all fields in one save.

The following handler implements the last step. It signs every named field with the organization's certificate and a trusted timestamp, and refuses to create the PDF while a field is still empty:

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

    List<string> missing = new List<string>();
    List<DigitalSignature> signatures = new List<DigitalSignature>();

    foreach (SignatureField field in textControl1.SignatureFields)
    {
        if (string.IsNullOrEmpty(field.Name))
        {
            continue;
        }

        // A field without an image hasn't been signed by its signer yet
        if (field.Image == null)
        {
            missing.Add(field.Name);
            continue;
        }

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

    if (missing.Count > 0)
    {
        MessageBox.Show(this, "Not signed yet: " + string.Join(", ", missing));
        return;
    }

    SaveSettings saveSettings = new SaveSettings()
    {
        SignatureFields = signatures.ToArray()
    };

    textControl1.Save("nda-signed.pdf", StreamType.AdobePDFA, saveSettings);
}
```

The code works as follows:

- [Image](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/signaturefield/image-property/llms-full.txt) is `null` for a field that has no signature image yet, so the loop collects the names of the fields that are still missing.
- Every other named field gets a `DigitalSignature` with the same certificate. When each signer has a certificate of their own on the certifying computer, create each `DigitalSignature` with that signer's certificate instead, as in the previous section.
- The PDF/A document is created only when all fields are signed. Until then, the document stays in the TX Text Control format and can still be changed.

The TX Text Control format and DOCX keep the signature fields with their names, images and signer data between the steps. Check who may open and change the file between two signers: before the certificates are applied, the images in the fields prove nothing.

### Check Documents With Several Signatures

Open the signed PDF in Adobe Acrobat Reader: the **Signatures** panel lists each signature with the name of its field, and clicking a signed field shows its validation status. The blog article [Understanding the Differences: 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/) compares a document signature and field signatures in the panel.

### Next Steps

- [Signature Fields and Signature Appearance](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/signature-fields/llms-full.txt): images and signer data of the fields.
- [Certificates](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/certificates/llms-full.txt): load a certificate per signer.
- [Timestamp Configuration](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/timestamps/llms-full.txt): add trusted timestamps to the signatures.

---

## Nearby

- **Previous:** [Signature Fields and Signature Appearance](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/signature-fields/llms-full.txt)
- **Next:** [Timestamp Configuration](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/timestamps/llms-full.txt)
