# Multiple Signatures

> Sign all signature fields of a PDF in one save: a DigitalSignature per field, several certificates and timestamps, sequential signers in the Document Viewer.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Digital Signatures > Multiple Signatures
- **3232 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/multiple/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/multiple/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/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 of a document gets its own certificate, its own timestamp and its own validation status. With TX Text Control, all of these signatures are applied in one save at the end of the signing process, after every party has signed the document electronically.

The API of signature fields, their images and their signer data are described in [Signature Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/signature-fields/llms-full.txt). The examples use *Documents/nda.tx*, the nondisclosure agreement created there, with the fields `sign_discloser`, `sign_vendor` and `init_vendor`.

### How Several Signatures Are Written

- **One `DigitalSignature` per field.** [SaveSettings.SignatureFields](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/signaturefields-property/llms-full.txt) takes an array of [DigitalSignature](https://docs.textcontrol.com/tx-text-control-dotnet-server/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 some with a trusted timestamp.
- **One save writes them all.** The certificates are applied while the PDF is created, so a document with several signatures is signed in a single save at the end of the process.
- **Each signature is verifiable on its own.** A signature of a field is bound to the part of the document that it covers, and each field keeps its own validation status.
- **Any later change invalidates the signatures.** Once the PDF is saved, a change to it breaks the signatures that cover the changed bytes. Archive signed documents without modifying them.
- **Signature fields, not a whole-document signature.** `SaveSettings.DigitalSignature` and `SaveSettings.SignatureFields` are two ways to sign. For several signatures, use signature fields.

TX Text Control can't add a signature to a PDF that is already signed. Signatures are created only when `ServerTextControl` saves its own document, and a PDF that it loads is rebuilt into a new document, as [Signing PDF Documents](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/signing/#after-the-document-is-signed) describes. Keep the document in the TX Text Control format or DOCX until all parties have signed, and create the signed PDF at the end.

### Sign Several Fields in One Save

The following program signs the three fields of the agreement 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:

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

// 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);

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Load("Documents/nda.tx", StreamType.InternalUnicodeFormat);

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

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

        if (field == null)
        {
            Console.WriteLine($"The document has no signature field named {name}.");
            return;
        }

        // The image shown in the field (filter index 8 is SVG)
        field.Image = new SignatureImage($"Documents/{name}.svg", 8);
    }

    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, null, "sign_vendor"),
            new DigitalSignature(vendorCertificate, null, "init_vendor")
        }
    };

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

The code works as follows:

- *vendor.pfx* is a second test certificate, created like *certificate.pfx* in [Self-Signed Certificates](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/self-signed/llms-full.txt). Every certificate needs its private key on the server.
- [SignatureFieldCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/signaturefieldcollection/getitem-method/llms-full.txt) checks that the document contains each field before it's signed, and [SignatureField.Image](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/signaturefield/image-property/llms-full.txt) sets the image of the signature, here from SVG 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 `null`.
- One `Save` call writes the PDF/A document with all three signatures.

### Collect Signatures From Several People

In most processes, the parties sign one after the other in the Document Viewer, and the server certifies the document when the last party has signed:

1. **Prepare the document** with one named field per signer, as [Documents With Several Signers](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/signature-fields/#documents-with-several-signers) shows.
2. **Send it to the first signer.** The viewer activates only that signer's fields, and its `TextControl` controller posts the signed document, in the TX Text Control format, to your endpoint.
3. **Send the signed document to the next signer**, who sees the signatures that are already there and signs their own fields.
4. **Certify the document** after the last signer: the server applies a certificate to every field and saves the PDF.

The following controller action implements steps 2 to 4 for the agreement. The discloser signs first and the vendor second, and the query string of `redirectUrlAfterSignature` tells the endpoint which signer submitted the document, as in [Documents With Several Signers](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/signature-fields/#documents-with-several-signers):

```csharp
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Mvc;
using TXTextControl;
using TXTextControl.Web.MVC.DocumentViewer.Models;

public class SignatureController : Controller
{
    [HttpPost]
    public IActionResult SignDocument([FromBody] SignatureData data, string signer)
    {
        byte[] signedDocument = Convert.FromBase64String(data.SignedDocument.Document);

        // The next signer continues with the document that contains this signature
        System.IO.File.WriteAllBytes($"App_Data/{data.UniqueId}.tx", signedDocument);

        // The discloser signs first; the vendor's signature completes the agreement
        if (signer != "vendor")
        {
            return Ok();
        }

        X509Certificate2 certificate = X509CertificateLoader.LoadPkcs12FromFile(
            "App_Data/certificate.pfx", "123", X509KeyStorageFlags.Exportable);

        using (ServerTextControl tx = new ServerTextControl())
        {
            tx.Create();
            tx.Load(signedDocument, BinaryStreamType.InternalUnicodeFormat);

            // Certify every named signature field in one save
            List<DigitalSignature> signatures = new List<DigitalSignature>();

            foreach (SignatureField field in tx.SignatureFields)
            {
                if (field.Name != "")
                {
                    signatures.Add(new DigitalSignature(certificate,
                        "http://timestamp.digicert.com", field.Name));
                }
            }

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

            tx.Save($"App_Data/{data.UniqueId}.pdf", StreamType.AdobePDFA, saveSettings);
        }

        return Ok();
    }
}
```

The code works as follows:

- [SignatureData.SignedDocument](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedata/signeddocument-property/llms-full.txt) contains the document with the signatures that the viewer merged into it, base64-encoded in the TX Text Control format.
- The document is stored under the [UniqueId](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedata/uniqueid-property/llms-full.txt) of the signing process. For the vendor, the viewer loads this file instead of the original template, so the discloser's signature is already in the document.
- After the vendor's signature, the server loads the document, adds a `DigitalSignature` with a timestamp for every named field and saves one PDF/A document with all signatures. In this example, the organization's certificate certifies each field.
- `UniqueId` and `signer` come from the browser. Check them against the signing processes your application started before you use them, for example in a file name, and protect the endpoint, as [Protect the Endpoint](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/digital-signatures/#protect-the-endpoint) describes.

The blog article [Electronic Signatures: Requesting Signatures from Multiple Signers using Custom Signature Workflows](https://www.textcontrol.com/blog/2023/01/02/electronic-signatures-requesting-signatures-from-multiple-signers-using-custom-signature-workflows/) collects only the signature images of each signer and applies them to the template at the end. The open-source application [SignFabric](https://github.com/TextControl/SignFabric) adds a routing order for sequential and grouped signers and creates the final signed PDF the same way.

### Check Documents With Several Signatures

A check of a document with several signatures looks at each of them. With the `TXTextControl.PDF.Validation` package, `report.Diagnostics.Signatures` reports every signature of the file with its integrity and the range it covers, as [Signature Validation](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/validation/#interpret-the-results) describes. In Adobe Acrobat Reader, the **Signatures** panel lists each signature with the name of its field.

### Next Steps

- [Signature Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/signature-fields/llms-full.txt): create signature fields and set their signer data.
- [Digital Signatures](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/digital-signatures/llms-full.txt) in Document Viewer: set up the signing process in the browser.
- [RFC 3161 Timestamps](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/timestamps/llms-full.txt): add trusted timestamps to the signatures.
- [Signature Validation](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/validation/llms-full.txt): check documents with several signatures.

---

## Nearby

- **Previous:** [RFC 3161 Timestamps](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/timestamps/llms-full.txt)
- **Next:** [Signature Validation](https://docs.textcontrol.com/tx-text-control-dotnet-server/digital-signatures/validation/llms-full.txt)
