Create a PDF Digital Signature Web Service Using Azure Key Vault and the Syncfusion C# PDF Library
Tags: fileformats, azure, blazor, csharp
Published: 2023-05-12 08:54:50

---
title: Create a PDF Digital Signature Web Service Using Azure Key Vault and the Syncfusion C# PDF Library
published: true
date: 2023-05-11 12:00:38 UTC
tags: fileformats, azure, blazor, csharp
canonical_url: https://www.syncfusion.com/blogs/post/pdf-digital-signature-web-service-using-azure-key-vault-and-csharp-pdf-library.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjcrfw7w7pzsjdfmtpqh.png
---
PDF files are widely used in various industries, and adding digital signatures to them is a necessary security measure. Digital signatures ensure the authenticity and integrity of a document, and they are legally binding. This blog post will explain the procedure to create a PDF digital signature service using [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault/ "Azure Key Vault") and the [Syncfusion PDF Library](https://www.syncfusion.com/document-processing/pdf-framework/net/pdf-library "Syncfusion PDF Library").

Azure Key Vault is a cloud-based key management service that allows you to create, store, and manage cryptographic keys and certificates. The Syncfusion PDF Library is a .NET library enabling you to programmatically create and manipulate PDF documents. Combining these powerful tools can create a robust and secure PDF digital signature service. ![Azure Key Vault working structure](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Azure-Key-Vault-working-structure.png)

In this blog, we will follow these steps to accomplish this goal:

1. [Create an Azure key vault and certificate.](#certificate)
2. [Register the app to access the Azure key vault.](#vault)
3. [Add the access policy to the Azure key vault.](#key)
4. [Create a PDF digital signature Web API service.](#service)
5. [Create a Blazor WebAssembly application with .NET 7.0.](#application)
6. [Launch the server and invoke the PDF digital signature service API from the client.](#client)

## Create an Azure key vault and certificate

Let’s first create an Azure key vault and certificate:

**Step 1:** First, create an Azure key vault resource in the [Azure portal](https://portal.azure.com/ "Azure portal"); please refer to this [link](https://learn.microsoft.com/en-us/azure/key-vault/general/quick-create-portal "Quickstart: Create a key vault using the Azure portal").

**Step 2:** Once the resource is created, go to the key vault, choose **Certificates** , and click **Generate/Import**. ![Choose Certificates, and click Generate/Import](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Choose-Certificates-and-click-GenerateImport.png)

**Step 3:** Choose **Generate** in the **Method of Certificate Creation** field **.** This option generates a new certificate. In this example, we have chosen **Self-signed certificate** as the type of certification authority. ![Choose Self-signed certificate as the type of certification authority](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Choose-Self-signed-certificate-as-the-type-of-certification-authority.png)

**Note:** You can also import a certificate from your local device by selecting **Import**.

![Choose Import option to import a certificate from local device](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Choose-Import-option-to-import-a-certificate-from-local-device.png)

**Step 4:** Next, select **Advanced Policy Configuration.** Choose **No** in the private key export option. ![Select Advanced Policy Configuration](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Select-Advanced-Policy-Configuration.png)

**Step 5:** Finally, click **Create**. The key vault certificate is now created under your account. ![Click Create to create key vault certificate](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Click-Create-to-create-key-vault-certificate.png)

You can click and open the properties of the certificate as follows. ![Created Azure key vault certificate](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Created-Azure-key-vault-and-certificate.png)

## Register the app to access the Azure key vault

To access the Azure key vault from the Web API, we must register it in [Azure Active Directory](https://azure.microsoft.com/en-ca/products/active-directory/ "Azure Active Directory"):

**Step 1:** Open **Azure Active Directory**. Select **App Registration** and click **New Registration**.

![Select App Registration and click New Registration](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Select-App-Registration-and-click-New-Registration.png)

**Step 2:** Enter your app name and proceed to register.

![Enter your app name and click on Register button](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Enter-your-app-name-and-click-on-Register-button.png)

Once registered, you will get the following information. Copy the **client ID** and **tenant ID** to use in the Web API. ![Copy the client ID and tenant ID](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Copy-the-client-ID-and-tenant-ID.png)

**Step 3:** Now select **API permissions** from the side menu and click **Add permission**. Select the Azure key vault, choose full access, and complete this process by clicking **Add permissions**. ![Click on Add permissions button](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Click-on-Add-permissions-button.png)

**Step 4:** Select the **Certificate & secrets** and click **New client secret** to create a new secret key. Copy this key to access it from Web API. ![Select the Certificate & secrets and click New client secret](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Select-the-Certificate-secrets-and-click-New-client-secret.png)

## Add the access policy to the Azure key vault

In the previous section, we created and registered the application. Now, we must provide Azure key vault access to this newly created application:

**Step 1:** Go to the Azure key vault, select **Access policies** , and click **Create**. ![Select Access policies and click Create](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Select-Access-policies-and-click-Create.png)

**Step 2:** Select the necessary permissions and click **Next**. ![Select the necessary permissions and click Next](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Select-the-necessary-permissions-and-click-Next.png)

**Step 3:** In this window, select the application we created in the previous section, **PDFDigitalSignatureService** , and click **Create**. ![Select the PDFDigitalSignatureService app](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Select-the-PDFDigitalSignatureService-app.png)

![Click on Create button](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Click-on-Create-button.png)

Now the application will be listed in the **Access policies** section.

![Navigate to the Access Policies section to view the created application](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Navigate-to-the-Access-Policies-section-to-view-the-created-application.png)

## Create a PDF digital signature Web API service

Now, we create a Web API to sign the PDF document digitally. To do this, create an ASP.NET Core minimal Web API. Refer to this [link](https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-7.0&tabs=visual-studio "Tutorial: Create a minimal API with ASP.NET Core").

Once the project is created, install the following NuGet packages as a reference from NuGet.org:

- [Azure.Security.KeyVault.Secrets](https://www.nuget.org/packages/Azure.Security.KeyVault.Secrets "Azure.Security.KeyVault.Secrets NuGet Package")
- [Azure.Identity](https://www.nuget.org/packages/Azure.Identity/ "Azure.Identity NuGet Package")
- [Azure.Security.KeyVault.Keys](https://www.nuget.org/packages/Azure.Security.KeyVault.Keys "Azure.Security.KeyVault.Keys NuGet Package")
- [Azure.Security.KeyVault.Certificates](https://www.nuget.org/packages/Azure.Security.KeyVault.Certificates "Azure.Security.KeyVault.Certificates NuGet Package")
- [Syncfusion.Pdf.Net.Core](https://www.nuget.org/packages/Syncfusion.Pdf.Net.Core "Syncfusion.Pdf.Net.Core NuGet Package")

Next, add a new API named **signPDF** in the **Program.cs** file.

```csharp
app.MapPost("api/signPDF", async (HttpContext context) =>
{
});
```

The certificate generated in Azure Key Vault cannot be exported or copied. However, it is possible to obtain the public portion of the certificate. We can digitally sign a PDF document using this public certificate along with the Azure key.

The following code retrieves the public portion of the certificate.

```csharp
X509Certificate2 GetPublicCertificate(ClientSecretCredential credential, String uri)
{
    //Create certificate client.
    CertificateClient certificateClient = new CertificateClient(new Uri(uri), credential);
 
    //Get the certificate with public key.
    KeyVaultCertificateWithPolicy certificate = certificateClient.GetCertificateAsync("PDFSigner").Result;
 
    //Create and return the X509Certificate2.
    return new X509Certificate2(certificate.Cer);
}
```

The following code is used to build the certificate chain if the certificate contains multiple certificates, such as root, intermediate, and issuer.

```csharp
//Get the public certificate to sign the PDF document.
X509Certificate2 pubCertifciate = GetPublicCertificate(credential, vaultUri);
 
//Build the certificate chain.
X509Chain chain = new X509Chain();
chain.Build(pubCertifciate);
 
List<X509Certificate2> certificates = new List<X509Certificate2>();
for (int i = 0; i < chain.ChainElements.Count; i++)
{
   certificates.Add(chain.ChainElements[i].Certificate);
}
```

Afterward, the external signer interface should be integrated to utilize the Azure key to externally sign the hash of the PDF document. The interface is designed to allow the retrieval of the hash of the PDF document, which has been processed through public certificates, and subsequently enable the signing of the document using the Azure key.

```csharp
//External signer to sign the PDF document using Azure Key Vault.
internal class ExternalSigner : IPdfExternalSigner
{
    public string HashAlgorithm => "SHA256";
    private CryptographyClient keyClient;
 
    public ExternalSigner(CryptographyClient client)
    {
        keyClient = client;
    }
 
    public byte[] Sign(byte[] message, out byte[] timeStampResponse)
    {
        var digest = SHA256.Create().ComputeHash(message);
        timeStampResponse = null;
 
        //Sign the hash of the PDF document
        return keyClient
            .SignAsync(
                SignatureAlgorithm.RS256,
                digest)
            .Result.Signature;
    }
}
```

The following complete code is used to sign the PDF document with the help of external signing.

```csharp
app.MapPost("api/signPDF", async (HttpContext context) =>
{
    var request = await context.Request.ReadFormAsync();
 
    if (request.Files.Count>0)
    {

        var pdfFile = request.Files[0].OpenReadStream();
        //Provide your azure key vault details here
        String tenantId = "tenantID";
        String clientId = "clientID";
        String secret = "secret";
        String vaultUri = "vault URI”;
 
        ClientSecretCredential credential = new ClientSecretCredential(tenantId, clientId, secret);
 
        //Get the public certificate to sign the PDF document.
        X509Certificate2 pubCertifciate = GetPublicCertificate(credential, vaultUri);
 
        //Build the certificate chain.
        X509Chain chain = new X509Chain();
        chain.Build(pubCertifciate);
 
        List<X509Certificate2> certificates = new List<X509Certificate2>();
        for (int i = 0; i < chain.ChainElements.Count; i++)
        {
            certificates.Add(chain.ChainElements[i].Certificate);
        }
        
        //Load the PDF document.
        PdfLoadedDocument loadedDocument = new PdfLoadedDocument(pdfFile);
 
        //Load the existing page.
        PdfLoadedPage? page = loadedDocument.Pages[0] as PdfLoadedPage;
 
        //Create a new PDF signature object.
        PdfSignature signature = new PdfSignature(loadedDocument, page!, null, "Sig1");
 
        signature.Bounds = new Syncfusion.Drawing.RectangleF(0, 0, 200, 100);
 
        //Create CryptographyClient with key identifier.
        CryptographyClient client = new CryptographyClient(new Uri("https://signature.vault.azure.net/keys/PDFSigner/adb90908592644f69e0e61bcf7c69ff4"), credential);
 
        //Signg using external signer.
        signature.AddExternalSigner(new ExternalSigner(client), certificates, null);
 
        signature.Settings.DigestAlgorithm = DigestAlgorithm.SHA256;
 
        MemoryStream ms = new MemoryStream();
 
        //Save and close the document.
        loadedDocument.Save(ms);
 
        ms.Position = 0;
 
        loadedDocument.Close(true);
 
        context.Response.ContentType = "application/pdf";
        await context.Response.Body.WriteAsync(ms.ToArray());
    }
});
```

Now that the web service has been created, it can be utilized in any application. For this blog, a Blazor WebAssembly (WASM) application will be developed to showcase the capabilities of the Web API service.

## Create Blazor WebAssembly app with .NET 7

The client application in this implementation is a Blazor WebAssembly application built with .NET version 7.0. To create a new ASP.NET Core Blazor WebAssembly application using [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/ "Visual Studio 2022"), please follow the guidance provided in [link](https://help.syncfusion.com/file-formats/pdf/create-pdf-document-in-blazor#steps-to-create-pdf-document-in-blazor-client-side-application "Steps to create PDF document in Blazor client-side application"). Within the application, we utilize the **HttpClient.PostAsync** method to send a POST request to the specified URI as an asynchronous operation.

```csharp
@code {
    private async Task SignPDF()
    {
        //Create http HTTP client to send both files and json JSON data.
        using (var client = new HttpClient())
        {
            //Create multipart form data content.
            using (var content = new MultipartFormDataContent())
            {
                var document = await Http.GetByteArrayAsync("PDF_Succinctly.pdf");
                content.Add(CreateContent("document", "input.pdf", document));
                //Calling web Web API to sign the PDF document.
                var response = await client.PostAsync("https://localhost:7171/api/signPDF", content);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    //Downloading the PDF document.
                    var responseContent = await response.Content.ReadAsStreamAsync();
                    using var Content = new DotNetStreamReference(stream: responseContent);
                    await JS.InvokeVoidAsync("SubmitHTML", "HTMLToPDF.pdf", Content);
                }
            }
        }
    }
    private ByteArrayContent CreateContent(string name, string fileName, byte[] fileBytes)
    {
        var fileContent = new ByteArrayContent(fileBytes);
        fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") 
        { 
            Name = name, 
            FileName = fileName 
        };
        return fileContent;
    }
}
```

Once the requested response status code is OK, invoke the JavaScript (JS) function in the **index.html** file to save the PDF document.

```xml
<script>
    window.SubmitHTML = async (fileName, contentStreamReference) => {
        const arrayBuffer = await contentStreamReference.arrayBuffer();
        const blob = new Blob([arrayBuffer]);
        const url = URL.createObjectURL(blob);
        const anchorElement = document.createElement('a');
        anchorElement.href = url;
        anchorElement.download = fileName ?? '';
        anchorElement.click();
        anchorElement.remove();
        URL.revokeObjectURL(url);
    }
</script>
```

While building and running the application, the website will open in your default browser. ![Launch the Created Blazor WebAssembly App](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Launch-the-Created-Blazor-WebAssembly-App.png)

## Launching the server and invoking the PDF digital signature service API from the client

Next, we launch the server and invoke the digital signature API from the client application.

**Step 1:** Run the Web API application to launch the published Web API in the browser.

**Step 2:** To sign a PDF document using the client application, send an asynchronous POST request to the specified URI (_e.g.,_ [https://localhost:7171/api/signPDF](https://localhost:7171/api/signPDF)) on the localhost. This will send the request to the server application, which will sign the PDF document using Azure Key Vault and send the response back to the client.

You will receive a PDF file upon successful signing, as illustrated in the following screenshot. ![PDF document with digital signature](https://www.syncfusion.com/blogs/wp-content/uploads/2023/05/Final-PDF-Digital-Signature-Output.png)

## GitHub samples

For better understanding, we have committed the source for this project in the [Sign PDFs using the Azure Key Vault](https://github.com/SyncfusionExamples/sign-pdf-using-azure-key-vault "Sign PDF Using Azure Key Vault demo on GitHub") GitHub repository.

## Conclusion

In this blog post, we have learned how to create our own PDF digital signature web service API to sign a PDF document using Azure Key Vault and the [Syncfusion C# PDF Library](https://www.syncfusion.com/document-processing/pdf-framework/net/pdf-library "Syncfusion PDF Library"). Now you can easily integrate this service into your application and customize it to add more features.

Take a moment to look at the [documentation](https://help.syncfusion.com/file-formats/pdf/working-with-digitalsignature "Working with Digital Signature in Syncfusion PDF Library"), where you will find other options and features, all with accompanying code samples.

For current Syncfusion customers, the newest version of Essential Studio is available from the [license and downloads page](https://www.syncfusion.com/account/downloads "Essential Studio license and downloads page").

Please let us know in the comments below if you have any questions about these features. You can also contact us through our [support forum](https://www.syncfusion.com/forums "Syncfusion Support Forum"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback/pdf "Syncfusion Feedback Portal"). We are happy to assist you!

## Related blogs

If you liked this article, we think you would also like the following articles about PDF Library:

- [Digitally Sign and Verify Signatures in PDF Files Using C#: A Complete Guide](https://www.syncfusion.com/blogs/post/create-validate-pdf-digital-signatures-csharp.aspx "Blog: Digitally Sign and Verify Signatures in PDF Files Using C#: A Complete Guide")
- [HTML-to-PDF Conversion in C# – A Complete Guide](https://www.syncfusion.com/blogs/post/html-to-pdf-conversion-in-csharp.aspx "Blog: HTML-to-PDF Conversion in C# – A Complete Guide")
- [Generate Dynamic PDF Reports from HTML Using C#](https://www.syncfusion.com/blogs/post/generate-dynamic-pdf-reports-from-html-template-using-csharp.aspx "Blog: Generate Dynamic PDF Reports from HTML Using C#")
- [How to Find Corrupted PDF Files in C# Easily](https://www.syncfusion.com/blogs/post/how-to-find-corrupted-pdf-files-in-c-sharp.aspx "Blog: How to Find Corrupted PDF Files in C# Easily")
- [Create Accessible PDF Documents Using C#](https://www.syncfusion.com/blogs/post/create-accessible-pdf-documents-using-c.aspx "Blog: Create Accessible PDF Documents Using C#")
- [Easy Ways to Redact PDFs Using C#](https://www.syncfusion.com/blogs/post/easy-ways-to-redact-pdfs-using-c.aspx "Blog: Easy Ways to Redact PDFs Using C#")
- [7 Ways to Compress PDF Files in C#, VB.NET](https://www.syncfusion.com/blogs/post/7-ways-to-compress-pdf-files.aspx "Blog: 7 Ways to Compress PDF Files in C#, VB.NET")