# Digital Signatures

> Collect signatures in the Document Viewer with SignatureSettings, the signature dialog and the Signatures object, then sign SignatureData with a certificate.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Document Viewer > Digital Signatures
- **4667 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/digital-signatures/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/digital-signatures/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/digital-signatures/llms-full.txt

---

In contract, approval or onboarding processes, users sign documents in the browser with the Document Viewer. Your application runs the signing process: it starts the process with signature settings, receives the signed document on the server and applies a certificate to it.

The examples extend the application of [Loading Documents](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/loading/llms-full.txt), whose `DocumentController` returns documents from the *App\_Data* folder. The document needs a signature field named `txsign`, which you insert in the Document Editor as described in [Signature Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/signature-fields/llms-full.txt). Save it as *contract.docx* in *App\_Data*.

### How Signing Works

1. **Load with signature settings.** Your code loads the document together with signature settings. They name the signature fields that users sign, the names shown to the user and the URL of an endpoint in your application.
2. **Sign.** The viewer shows a signature bar and turns the named signature fields into signature boxes. Users click a box and create their signature in a dialog: they draw it with the mouse or a finger, type their name in a font, or upload an image.
3. **Submit.** When users submit the document, the backend of the viewer merges the signature images and the values of form fields into the document.
4. **Process on the server.** The backend of the viewer then posts the signed document and the signature data on to your endpoint: the request comes from the viewer's `TextControl` controller in your application, not from the browser. There, your code can apply a certificate to each signature field and save a digitally signed PDF document.
5. **Return a result.** What your endpoint returns is passed to a callback in the browser, for example to offer the signed PDF document for download.

Electronic signatures are the images that users create in the viewer. A digital signature additionally applies a certificate to the document; [Digitally Sign a PDF](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/pdf/sign/llms-full.txt) explains certificates.

### Start the Signing Process

The following view renders the viewer without a document, loads *contract.docx* from the `DocumentController` with signature settings and downloads the signed PDF document that the endpoint returns. Replace the content of *Views/Home/Index.cshtml*:

```cshtml
@using TXTextControl.Web.MVC.DocumentViewer

<div style="width: 800px; height: 600px;">

@Html.TXTextControl().DocumentViewer(settings => {
    settings.Dock = DocumentViewerSettings.DockStyle.Fill;
}).Render()

</div>

<script>
    window.addEventListener("documentViewerLoaded", async function () {
        TXDocumentViewer.addEventListener("signaturesCompleted", function () {
            console.log("All signature boxes are signed.");
        });

        // Receives the string that SignatureController.SignDocument returns
        TXDocumentViewer.signatures.setSubmitCallback(function (result) {
            var link = document.createElement("a");
            link.href = "data:application/pdf;base64," + result;
            link.download = "signed.pdf";
            document.body.appendChild(link);
            link.click();
        });

        const response = await fetch("/Document/Load?name=contract.docx");
        const stored = await response.json();

        await TXDocumentViewer.loadDocument(stored.data, stored.name, {
            showSignatureBar: true,
            ownerName: "Paul Paulsen",
            signerName: "Tim Typer",
            signerInitials: "TT",
            uniqueId: "12345-ABCDE",
            redirectUrlAfterSignature: window.location.origin + "/Signature/SignDocument",
            signatureBoxes: [ { name: "txsign", signingRequired: true, style: 0 } ]
        });
    });
</script>
```

The code works as follows:

- [loadDocument](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/documentviewercontroller/loaddocument-method/llms-full.txt) takes a [SignatureSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/llms-full.txt) object as its third parameter, which starts the signing process for this document.
- [signatureBoxes](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/signatureboxes-property/llms-full.txt) lists the signature fields that users sign. [Signature Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/signature-fields/llms-full.txt) describes the boxes.
- [setSubmitCallback](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/setsubmitcallback-method/llms-full.txt) registers the function that is called when the document has been submitted. It receives the string that your endpoint returns, here the signed PDF document as base64-encoded data.
- The `signaturesCompleted` event is raised when the user has signed all signature boxes.

The signature settings have these properties:

| Property | Sets |
|---|---|
| [showSignatureBar](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/showsignaturebar-property/llms-full.txt) | Whether the signature bar with an introductory text is shown at the top of the viewer |
| [ownerName](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/ownername-property/llms-full.txt) | The name of the person who requests the signature, shown in the signature bar |
| [signerName](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/signername-property/llms-full.txt), [signerInitials](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/signerinitials-property/llms-full.txt) | The name and initials of the signer, shown in the signature dialog |
| [uniqueId](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/uniqueid-property/llms-full.txt) | A unique ID of the document, such as an envelope ID, included in the representation of the signature |
| [redirectUrlAfterSignature](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/redirecturlaftersignature-property/llms-full.txt) | The URL of the endpoint that receives the signed document |
| [signatureBoxes](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/signatureboxes-property/llms-full.txt) | The signature fields that users sign |
| [defaultSignatureFont](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/defaultsignaturefont-property/llms-full.txt) | The font preselected for typed signatures, for example `{ family: "Pacifico" }` |
| [customSigning](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signaturesettings/customsigning-property/llms-full.txt) | Whether your code handles the signing on the server; see "Custom Signing" below |

The older `signatureBoxName` is obsolete; use `signatureBoxes`. In the ASP.NET Core view, the same settings are available as [DocumentViewerSettings.SignatureSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer/documentviewersettings/signaturesettings-property/llms-full.txt) with a .NET [SignatureSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer/signaturesettings/llms-full.txt) object, and in Angular and React as the `signatureSettings` property.

### Receive and Sign the Document on the Server

The viewer's `TextControl` controller posts a [SignatureData](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedata/llms-full.txt) object to the URL of `redirectUrlAfterSignature`. The following controller loads the signed document, applies a certificate to each signature box and returns the PDF document. Create *Controllers/SignatureController.cs*, and put a certificate file *certificate.pfx* with the password `123` into *App\_Data*, as created in [Digitally Sign a PDF](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/pdf/sign/#create-a-self-signed-certificate-for-testing):

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

public class SignatureController : Controller
{
    [HttpPost]
    public string SignDocument([FromBody] SignatureData data)
    {
        X509Certificate2 certificate = X509CertificateLoader.LoadPkcs12FromFile(
            "App_Data/certificate.pfx", "123", X509KeyStorageFlags.Exportable);

        // One certificate for each signature box of this signing process
        List<DigitalSignature> signatures = new List<DigitalSignature>();
        foreach (SignatureBox box in data.SignatureBoxes)
        {
            signatures.Add(new DigitalSignature(certificate, null, box.Name));
        }

        byte[] pdf;

        using (ServerTextControl tx = new ServerTextControl())
        {
            tx.Create();

            // The signed document arrives base64-encoded in the TX Text Control format
            tx.Load(Convert.FromBase64String(data.SignedDocument.Document),
                BinaryStreamType.InternalUnicodeFormat);

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

            tx.Save(out pdf, BinaryStreamType.AdobePDF, saveSettings);
        }

        // Passed as a string to the setSubmitCallback function
        return Convert.ToBase64String(pdf);
    }
}
```

The code works as follows:

- `[FromBody]` binds the posted data to `SignatureData`. [SignatureBoxes](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedata/signatureboxes-property/llms-full.txt) contains the signature boxes of the process, and [SignedDocument](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedata/signeddocument-property/llms-full.txt) the document with the signatures merged in.
- A [DigitalSignature](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/digitalsignature/llms-full.txt) associates the certificate with the signature field of the given name.
- [ServerTextControl.Load](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/load-method/llms-full.txt) loads the [Document](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedocument/document-property/llms-full.txt) of the signed document, which is base64-encoded data in the TX Text Control format.
- [SaveSettings.SignatureFields](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/signaturefields-property/llms-full.txt) takes the digital signatures, and [Save](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/save-method/llms-full.txt) writes the signed PDF document.

`X509CertificateLoader` is available in .NET 9 and later; in a .NET 8 project, load the certificate with `new X509Certificate2("App_Data/certificate.pfx", "123", X509KeyStorageFlags.Exportable)`.

Run the application, click the signature box, create a signature and submit the document: the browser downloads *signed.pdf*, whose signature field is digitally signed.

`SignatureData` also contains the signature image as base64-encoded data in [SignatureImage](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedata/signatureimage-property/llms-full.txt), the values of the form fields in [FormFields](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedata/formfields-property/llms-full.txt) and the ID of the document in [UniqueId](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc-documentviewer-models/signaturedata/uniqueid-property/llms-full.txt). The endpoint can be part of another application, and values in the query string of its URL reach the action as parameters, for example an ID of the signer.

### What Users See

The signer goes through these steps in the viewer, shown here with the settings of the view above:

1. The signature bar asks the signer to review and sign the document, and a **SIGN HERE** marker points to each signature box:

    ![The Document Viewer with the blue signature bar "Paul Paulsen asked you to review and sign this document. To start the process of signing this document, please click 'Next'.", a NEXT button and a yellow signature box marked SIGN HERE](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-server/viewer-signature-bar.bdda0cac.webp)
2. **NEXT** or a click on a signature box opens the **Setup your Signature** dialog with the signer's name and initials from the settings. The buttons above the signature pad switch between drawing, typing and uploading an image, and **SETUP AND SIGN** is available once there is a signature:

    ![The Setup your Signature dialog with the full name Tim Typer, the initials TT, a signature drawn with the mouse, and the SETUP AND SIGN and CANCEL buttons](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-server/viewer-signature-dialog.0f39c3a5.webp)
3. The bar asks the signer to confirm the signature by clicking the yellow signature areas. Each click puts the signature into a box.
4. When all boxes are signed, the bar says that the signing process is complete, and **SUBMIT** sends the document to the backend:

    ![The signed box with the drawn signature and a green check mark, below the bar "The signing process is complete. Please submit your signed document." with a SUBMIT button](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-server/viewer-signature-submit.8b9ac9fb.webp)

- **The signature bar** at the top of the viewer shows the owner's name while the signing process is active.
- **The signature dialog** opens when users click a signature box. Since version 32.1.1 of the Document Viewer package, it offers three ways to create a signature: draw it, type the name in a font of their choice or upload an image. The fonts that your page loads are offered for typed signatures.
- **A stored signature.** The browser stores the signatures users create locally, so they can use them again in later sessions. [clearSignaturePad](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/clearsignaturepad-method/llms-full.txt) clears the signature pad of the dialog.
- **Initials boxes** are signed with the initials the user enters in the dialog.

### Control the Signing Process

The [Signatures](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/llms-full.txt) object, `TXDocumentViewer.signatures`, has these methods:

| Method | Does |
|---|---|
| [startSigningProcess](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/startsigningprocess-method/llms-full.txt) | Starts the signing process and opens the signature dialog |
| [cancelSigningProcess](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/cancelsigningprocess-method/llms-full.txt) | Cancels the setup of the signature and closes the dialog |
| [submit](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/submit-method/llms-full.txt) | Submits the signed document |
| [setSubmitCallback](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/setsubmitcallback-method/llms-full.txt) | Sets the function that is called when the document is submitted |
| [setBeforeSubmitCallback](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/setbeforesubmitcallback-method/llms-full.txt) | Sets the function that is called when the document is being submitted |
| [setCustomSigning](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/setcustomsigning-method/llms-full.txt), [getCustomSigning](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/getcustomsigning-method/llms-full.txt) | Turn custom signing on or off and return its state |
| [retrieveSignature](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/retrievesignature-method/llms-full.txt), [clearSignaturePad](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript-document-viewer/signatures/clearsignaturepad-method/llms-full.txt) | Retrieve the signature stored in the browser and clear the signature dialog |

To submit the document as soon as all boxes are signed, call `TXDocumentViewer.signatures.submit()` in the handler of `signaturesCompleted`.

### Custom Signing

With custom signing, turned on with `customSigning: true` or `setCustomSigning(true)`, the viewer forwards only the signature data to your endpoint, and your code creates the signed document itself. The endpoint receives the signature image in `SignatureData.SignatureImage` and the names of the boxes in `SignatureBoxes`, and can insert the image into the fields of the original document with `ServerTextControl`. The blog article [Electronic Signatures: Document Signing by Routing Requests to Custom Endpoints](https://www.textcontrol.com/blog/2022/02/03/electronic-signatures-custom-signing-processes/) compares the default and the custom process.

### Protect the Endpoint

The endpoint accepts every document that is posted to it, so check that each request belongs to a signing process your application started. A common approach adds a token that your server generated to the query string of `redirectUrlAfterSignature` and checks it in a filter before the action runs; [Protect the Signing Endpoint](https://docs.textcontrol.com/tx-text-control-dotnet-server/security/signatures/#protect-the-signing-endpoint) in Security shows this filter. The blog article [How to Add Electronic and Digital Signatures to PDFs in ASP.NET Core C# and Angular](https://www.textcontrol.com/blog/2024/03/20/how-to-add-electronic-and-digital-signatures-to-pdfs-in-asp-net-core-c-sharp-and-angular/) builds the complete process with Angular.

### Next Steps

- [Signature Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/signature-fields/llms-full.txt): signature and initials boxes, and documents with several signers.
- [Digitally Sign a PDF](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/pdf/sign/llms-full.txt): certificates, timestamps and verifying signatures.
- [Form Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/form-fields/llms-full.txt): let users fill out the document before they sign it.

---

## Nearby

- **Previous:** [Form Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/form-fields/llms-full.txt)
- **Next:** [Signature Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/signature-fields/llms-full.txt)
