PRODUCT COMPARISONS

Add Digital Signature to PDF in C# Using Itextsharp

Chipego
Chipego Kalinda
April 24, 2025
Share:

Introduction

In today’s fast-paced digital world, physical paperwork is rapidly being replaced by electronic documents. Whether it’s signing a contract, approving an invoice, or submitting a government form, digital documentation has become the new normal. But with convenience comes a new concern: how do you ensure the authenticity and integrity of those digital documents?

Enter electronic signatures. Much more than a scribble on a touchscreen, digital signatures use cryptographic techniques to verify the signer’s identity and guarantee that the contents of a document haven't been altered. For C# developers, integrating this level of security into PDF workflows is easier than ever—especially with tools like IronPDF and iTextSharp. In this article, we’ll walk through the process of digitally signing PDFs, compare libraries, provide best practices, and help you choose the right solution for your next project.

Understanding Digital Signatures

A digital signature is a cryptographic technique used to validate the authenticity and integrity of a digital message or document. Unlike a simple image-based signature or a typed name, a digital signature uses a private key to encrypt a hash of the document. This encrypted hash can then be verified by anyone using the signer's public key.

Why does this matter? Because it ensures two things:

  1. Authentication – The signature is used to verify PDF documents that came from the stated sender.

  2. Integrity – The document has not been altered since it was signed. Even a tiny change invalidates the signature.

Digital signatures are legally binding in many jurisdictions and are vital in industries like finance, healthcare, legal, and government.

Why Use Digital Signatures in PDFs?

PDFs are the standard format for distributing professional documents, from legal contracts to official reports. Adding digital signatures to PDFs serves several critical purposes:

  • Legality & Compliance: Digital signatures comply with regulations like eIDAS (Europe), ESIGN (U.S.), and others, making them legally recognized.

  • Security: Signed documents can't be altered without breaking the signature, protecting against tampering or fraud.

  • Efficiency: No need to print, sign, and scan. Save time and streamline workflows with secure digital approvals.

  • Trust: Clients and partners can confidently verify the origin and integrity of documents.

In short, digital signatures bring trust and efficiency to your document workflows.

Comparing iTextSharp and IronPDF

When implementing digital signatures in C#, two libraries often stand out: iTextSharp and IronPDF. Both are capable tools, but they cater to different types of developers and project requirements. Let’s break down how they compare in real-world usage.

iTextSharp: Power with Complexity

iTextSharp is a well-known name in the world of PDF manipulation. It’s a part of the broader iText 7 ecosystem, offering extensive support for low-level PDF operations, including cryptographic digital signing.

Developers who need fine-grained control over signature appearance, hashing algorithms, certificate chains, and custom validation workflows will find iTextSharp very capable. It’s highly extensible and designed with complex enterprise needs in mind.

However, that flexibility comes at a cost. The learning curve is steep. Simple tasks, such as adding a visible signature, often require multiple classes, streams, and configuration steps. For new users, this can be overwhelming.

Additionally, iTextSharp is licensed under the AGPL, which requires your application to be open-source unless you purchase a commercial license—a deal-breaker for many closed-source or proprietary projects.

IronPDF: Simplicity Meets Professionalism

IronPDF, in contrast, takes a modern, developer-first approach. Its API is designed to handle common PDF tasks—like digital signatures, generation, merging, and editing—with minimal setup. What might take a dozen steps in iTextSharp often takes just one or two lines in IronPDF. This makes is a powerful PDF library for .NET framework projects.

For example, signing a PDF in IronPDF doesn’t require working directly with streams or cryptographic settings. You simply load the PDF, call .SignPdf(), and pass in your certificate. It even supports extra metadata like the signer’s location, reason, and contact info—all in a single method call.

Another key benefit is licensing. IronPDF offers a commercial-friendly license without AGPL restrictions, which is ideal for professional and enterprise-grade applications. And while it is a paid product, a generous free trial makes it easy to evaluate before committing.

Side-by-Side Summary

FeatureiTextSharpIronPDF
Ease of UseSteep learning curveBeginner-friendly, minimal code
LicenseAGPL (or paid commercial license)Commercial license with no open-source mandate
Signature CustomizationHighly customizable with cryptography controlSimplified API with optional metadata fields
DocumentationDetailed, but denseClear examples with developer-focused docs
Best ForEnterprise applications with deep customizationTeams needing rapid implementation and support

Getting Started with iTextSharp and IronPDF

Before diving into digital signature implementations, it’s crucial to understand how to get up and running with each library. Whether you're building an enterprise-grade solution or a quick in-house tool, the right setup can make all the difference.

Setting Up iTextSharp

iTextSharp is the .NET port of the powerful Java-based iText PDF library. To get started, you’ll need to install it via NuGet and reference the right namespaces in your project.

Installation

You can install the iTextSharp library into your project with ease through the NuGet Package Manager console. All you need to do is run the following command:

Install-Package iTextSharp
Install-Package iTextSharp
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package iTextSharp
$vbLabelText   $csharpLabel

Installing iTextSharp

This easy installation ensures quick implementation of this library within your C# project.

Basic Setup

Once installed, you can start using iTextSharp namespaces in your project:

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
Imports iTextSharp.text.pdf
Imports iTextSharp.text.pdf.security
$vbLabelText   $csharpLabel

Keep in mind that iTextSharp is modular. If you plan to use advanced cryptographic features or time stamping, you’ll likely need additional packages like BouncyCastle.Cryptography. This can be installed similarly to iTextSharp, just run the line:

Install-Package BouncyCastle.Cryptography
Install-Package BouncyCastle.Cryptography
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package BouncyCastle.Cryptography
$vbLabelText   $csharpLabel

Things to Watch For

  • Licensing: The AGPL license requires any software using iTextSharp to be open-source unless you purchase a commercial license.

  • Dependencies: Cryptographic operations often require BouncyCastle for certificate handling.

  • Learning Curve: Even basic signing involves understanding PdfSigner, IExternalSignature, and various cryptographic providers.

If you’re comfortable configuring these building blocks and need full control over the signing process (e.g., setting appearance, validation level, or timestamping servers), iTextSharp is a solid choice.

Setting Up IronPDF

IronPDF is a commercial PDF library built with developer productivity in mind. It's designed for .NET developers who want to generate, edit, and sign PDFs with minimal hassle. IronPDF offers a much smoother onboarding experience, especially for those who value clean APIs and quick results.

Installation

Install the latest IronPDF package via NuGet:

Install-Package IronPdf
Install-Package IronPdf
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package IronPdf
$vbLabelText   $csharpLabel

Installing IronPDF through the NuGet console

Or use the .NET CLI:

dotnet add package IronPdf
dotnet add package IronPdf
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet add package IronPdf
$vbLabelText   $csharpLabel

Basic Setup

Start by importing the main IronPDF namespace:

using IronPdf;
using IronPdf;
Imports IronPdf
$vbLabelText   $csharpLabel

That’s it—you’re ready to load a PDF and start adding digital signatures.

IronPDF manages everything internally: certificate loading, visible signature positioning, metadata, and final export. You don’t have to manage PDF streams or cryptographic algorithms manually, which is a huge advantage for rapid development.

Key Advantages for Beginners

  • All-in-One: No extra dependencies or cryptography libraries needed.

  • No AGPL worries: IronPDF offers a perpetual license and a generous free trial.

  • Visual Rendering: IronPDF renders PDFs exactly as they’d appear when printed, making it ideal for contracts and official documents.

Step-by-Step: Adding a Digital Signature

1. Prepare Your Certificate

You’ll need a .pfx digital certificate file and a password. These are used to generate the digital signature. You can obtain a certificate from a trusted Certificate Authority (CA) or generate one for internal use using tools like OpenSSL.

2. PDF Signing with iTextSharp and BouncyCastle

Include the necessary namespaces

First, we need to ensure we have the correct using statements at the top of the code in order to access the various classes and methods required to sign a PDF digitally with iTextSharp.

using System;
using System.IO;
using System.Linq;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
using System;
using System.IO;
using System.Linq;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
Imports System
Imports System.IO
Imports System.Linq
Imports iTextSharp.text.pdf
Imports iTextSharp.text.pdf.security
Imports Org.BouncyCastle.Crypto
Imports Org.BouncyCastle.Pkcs
$vbLabelText   $csharpLabel

Define Input PDF and Load it into PdfReader

We the specify the path to the existing PDF and loading it into a PdfReader. We will also assign some string variables that will be used later in the code.

// Path to the unsigned PDF you want to sign
string filename = "example.pdf";

// Load the existing PDF into a reader
PdfReader pdfReader = new PdfReader(filename);

string reason = "Digital Signature Reason";
string location = "Digital Signature Location";
// Path to the unsigned PDF you want to sign
string filename = "example.pdf";

// Load the existing PDF into a reader
PdfReader pdfReader = new PdfReader(filename);

string reason = "Digital Signature Reason";
string location = "Digital Signature Location";
' Path to the unsigned PDF you want to sign
Dim filename As String = "example.pdf"

' Load the existing PDF into a reader
Dim pdfReader As New PdfReader(filename)

Dim reason As String = "Digital Signature Reason"
Dim location As String = "Digital Signature Location"
$vbLabelText   $csharpLabel

Define Certificate Path and Password

Next, we point to the .pfx certificate file and provide the password used to protect it.

// Path to your .pfx certificate file (must contain private key)
string pfxFilePath = "certificate-file.pfx";

// Password for the certificate (make sure to protect this securely!)
string pfxPassword = "Password";
// Path to your .pfx certificate file (must contain private key)
string pfxFilePath = "certificate-file.pfx";

// Password for the certificate (make sure to protect this securely!)
string pfxPassword = "Password";
' Path to your .pfx certificate file (must contain private key)
Dim pfxFilePath As String = "certificate-file.pfx"

' Password for the certificate (make sure to protect this securely!)
Dim pfxPassword As String = "Password"
$vbLabelText   $csharpLabel

Load the .PFX Certificate Using Pkcs12Store

We use BouncyCastle to load the certificate and private key into a secure store.

// Initialize a new PKCS#12 key store (used for handling the PFX certificate)
Pkcs12StoreBuilder Pkcs12StoreBuilder = new Pkcs12StoreBuilder();
Pkcs12Store pfxKeyStore = Pkcs12StoreBuilder.Build();

// Load the certificate and private key from the PFX file
using (FileStream pfxStream = new FileStream(pfxFilePath, FileMode.Open, FileAccess.Read))
{
    // Load into the key store using the provided password
    pfxKeyStore.Load(pfxStream, pfxPassword.ToCharArray());
}
// Initialize a new PKCS#12 key store (used for handling the PFX certificate)
Pkcs12StoreBuilder Pkcs12StoreBuilder = new Pkcs12StoreBuilder();
Pkcs12Store pfxKeyStore = Pkcs12StoreBuilder.Build();

// Load the certificate and private key from the PFX file
using (FileStream pfxStream = new FileStream(pfxFilePath, FileMode.Open, FileAccess.Read))
{
    // Load into the key store using the provided password
    pfxKeyStore.Load(pfxStream, pfxPassword.ToCharArray());
}
' Initialize a new PKCS#12 key store (used for handling the PFX certificate)
Dim Pkcs12StoreBuilder As New Pkcs12StoreBuilder()
Dim pfxKeyStore As Pkcs12Store = Pkcs12StoreBuilder.Build()

' Load the certificate and private key from the PFX file
Using pfxStream As New FileStream(pfxFilePath, FileMode.Open, FileAccess.Read)
	' Load into the key store using the provided password
	pfxKeyStore.Load(pfxStream, pfxPassword.ToCharArray())
End Using
$vbLabelText   $csharpLabel

Prepare PdfStamper for Adding a Signature

A PdfStamper lets us apply a digital signature while preserving the original content.

// Create a PdfStamper that enables signing and appends the signature to the document
PdfStamper pdfStamper = PdfStamper.CreateSignature(
    pdfReader,
    new FileStream("MyPDF_Signed.pdf", FileMode.Create), // Output path
    '\0',                                                // PDF version (unchanged)
    null,                                                // Temp file path (optional)
    true                                                 // Append mode (preserves original content)
);
// Create a PdfStamper that enables signing and appends the signature to the document
PdfStamper pdfStamper = PdfStamper.CreateSignature(
    pdfReader,
    new FileStream("MyPDF_Signed.pdf", FileMode.Create), // Output path
    '\0',                                                // PDF version (unchanged)
    null,                                                // Temp file path (optional)
    true                                                 // Append mode (preserves original content)
);
Imports Microsoft.VisualBasic

' Create a PdfStamper that enables signing and appends the signature to the document
Dim pdfStamper As PdfStamper = PdfStamper.CreateSignature(pdfReader, New FileStream("MyPDF_Signed.pdf", FileMode.Create), ControlChars.NullChar, Nothing, True)
$vbLabelText   $csharpLabel

Customize the Signature Appearance

Now we define how and where the signature will appear visually in the document.

// Access the signature appearance settings
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;

// Add optional metadata (shows up in PDF signature details)
signatureAppearance.Reason = reason;
signatureAppearance.Location = location;

// Position the visible signature on the page (x, y, width, height in points)
float x = 360;
float y = 130;
signatureAppearance.Acro6Layers = false; // Use compact signature appearance
signatureAppearance.Layer4Text = PdfSignatureAppearance.questionMark; // Custom label text
signatureAppearance.SetVisibleSignature(
    new iTextSharp.text.Rectangle(x, y, x + 150, y + 50), // Rectangle position
    1,                                                    // Page number
    "signature"                                           // Field name
);
// Access the signature appearance settings
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;

// Add optional metadata (shows up in PDF signature details)
signatureAppearance.Reason = reason;
signatureAppearance.Location = location;

// Position the visible signature on the page (x, y, width, height in points)
float x = 360;
float y = 130;
signatureAppearance.Acro6Layers = false; // Use compact signature appearance
signatureAppearance.Layer4Text = PdfSignatureAppearance.questionMark; // Custom label text
signatureAppearance.SetVisibleSignature(
    new iTextSharp.text.Rectangle(x, y, x + 150, y + 50), // Rectangle position
    1,                                                    // Page number
    "signature"                                           // Field name
);
' Access the signature appearance settings
Dim signatureAppearance As PdfSignatureAppearance = pdfStamper.SignatureAppearance

' Add optional metadata (shows up in PDF signature details)
signatureAppearance.Reason = reason
signatureAppearance.Location = location

' Position the visible signature on the page (x, y, width, height in points)
Dim x As Single = 360
Dim y As Single = 130
signatureAppearance.Acro6Layers = False ' Use compact signature appearance
signatureAppearance.Layer4Text = PdfSignatureAppearance.questionMark ' Custom label text
signatureAppearance.SetVisibleSignature(New iTextSharp.text.Rectangle(x, y, x + 150, y + 50), 1, "signature")
$vbLabelText   $csharpLabel

Extract the Private Key and Sign the PDF

We retrieve the alias (name) of the certificate entry that contains the private key. If the alias exists, we proceed to generate and embed the digital signature using SHA-256.

// Find the first alias in the PFX that has a private key entry
string alias = pfxKeyStore.Aliases.Cast<string>().FirstOrDefault(
    entryAlias => pfxKeyStore.IsKeyEntry(entryAlias)
);

// Ensure a valid alias (certificate) was found
if (alias != null)
{
    // Retrieve the private key for signing
    ICipherParameters privateKey = pfxKeyStore.GetKey(alias).Key;

    // Create a signer using SHA-256 and the private key
    IExternalSignature pks = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256);

    // Perform the digital signing operation using CMS format
    MakeSignature.SignDetached(
        signatureAppearance,     // Signature appearance
        pks,                     // External signature handler
        new Org.BouncyCastle.X509.X509Certificate[] {
            pfxKeyStore.GetCertificate(alias).Certificate
        },                       // Certificate chain (basic single-cert example)
        null, null, null,        // Optional CRL, OCSP, TSA
        0,                       // Estimated size for the signature (0 = auto)
        CryptoStandard.CMS       // Signature standard (CMS vs CAdES)
    );
}
else
{
    Console.WriteLine("Private key not found in the PFX certificate.");
}
// Find the first alias in the PFX that has a private key entry
string alias = pfxKeyStore.Aliases.Cast<string>().FirstOrDefault(
    entryAlias => pfxKeyStore.IsKeyEntry(entryAlias)
);

// Ensure a valid alias (certificate) was found
if (alias != null)
{
    // Retrieve the private key for signing
    ICipherParameters privateKey = pfxKeyStore.GetKey(alias).Key;

    // Create a signer using SHA-256 and the private key
    IExternalSignature pks = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256);

    // Perform the digital signing operation using CMS format
    MakeSignature.SignDetached(
        signatureAppearance,     // Signature appearance
        pks,                     // External signature handler
        new Org.BouncyCastle.X509.X509Certificate[] {
            pfxKeyStore.GetCertificate(alias).Certificate
        },                       // Certificate chain (basic single-cert example)
        null, null, null,        // Optional CRL, OCSP, TSA
        0,                       // Estimated size for the signature (0 = auto)
        CryptoStandard.CMS       // Signature standard (CMS vs CAdES)
    );
}
else
{
    Console.WriteLine("Private key not found in the PFX certificate.");
}
' Find the first alias in the PFX that has a private key entry
Dim [alias] As String = pfxKeyStore.Aliases.Cast(Of String)().FirstOrDefault(Function(entryAlias) pfxKeyStore.IsKeyEntry(entryAlias))

' Ensure a valid alias (certificate) was found
If [alias] IsNot Nothing Then
	' Retrieve the private key for signing
	Dim privateKey As ICipherParameters = pfxKeyStore.GetKey([alias]).Key

	' Create a signer using SHA-256 and the private key
	Dim pks As IExternalSignature = New PrivateKeySignature(privateKey, DigestAlgorithms.SHA256)

	' Perform the digital signing operation using CMS format
	MakeSignature.SignDetached(signatureAppearance, pks, New Org.BouncyCastle.X509.X509Certificate() { pfxKeyStore.GetCertificate([alias]).Certificate }, Nothing, Nothing, Nothing, 0, CryptoStandard.CMS)
Else
	Console.WriteLine("Private key not found in the PFX certificate.")
End If
$vbLabelText   $csharpLabel

Finalize the Document

Finally, we close the stamper to complete the signing process and write the signed PDF to disk.

// Close the stamper to save and finalize the signed PDF
pdfStamper.Close();
// Close the stamper to save and finalize the signed PDF
pdfStamper.Close();
' Close the stamper to save and finalize the signed PDF
pdfStamper.Close()
$vbLabelText   $csharpLabel

Output

PDF signed using iTextSharp

3. Digitally Sign PDFs in C# Using IronPDF

Include the necessary namespaces

We start by importing the necessary namespaces for working with PDF signing, certificate handling, and image positioning.

using IronPdf;
using IronPdf.Signing;
using IronSoftware.Drawing;
using System.Security.Cryptography.X509Certificates;
using IronPdf;
using IronPdf.Signing;
using IronSoftware.Drawing;
using System.Security.Cryptography.X509Certificates;
Imports IronPdf
Imports IronPdf.Signing
Imports IronSoftware.Drawing
Imports System.Security.Cryptography.X509Certificates
$vbLabelText   $csharpLabel

Load the PDF you want to sign

We load an existing PDF file from disk using IronPDF's simple PdfDocument API. You can also create a new PDF document for this task.

var pdf = PdfDocument.FromFile("example.pdf");
var pdf = PdfDocument.FromFile("example.pdf");
Dim pdf = PdfDocument.FromFile("example.pdf")
$vbLabelText   $csharpLabel

Load the PFX certificate used for signing

We load the .pfx certificate containing the private key. The Exportable flag is required so the signing key can be accessed.

X509Certificate2 cert = new X509Certificate2(
    "IronSoftware.pfx",
    "Password",
    X509KeyStorageFlags.Exportable
);
X509Certificate2 cert = new X509Certificate2(
    "IronSoftware.pfx",
    "Password",
    X509KeyStorageFlags.Exportable
);
Dim cert As New X509Certificate2("IronSoftware.pfx", "Password", X509KeyStorageFlags.Exportable)
$vbLabelText   $csharpLabel

Create a new PdfSignature using the certificate

We create a new PdfSignature object from the loaded certificate.

var sig = new PdfSignature(cert);
var sig = new PdfSignature(cert);
Dim sig = New PdfSignature(cert)
$vbLabelText   $csharpLabel

Apply the signature and save the output

We digitally sign the PDF and save the signed PDF document as a new file.

pdf.Sign(sig);
pdf.SaveAs("signed.pdf");
pdf.Sign(sig);
pdf.SaveAs("signed.pdf");
pdf.Sign(sig)
pdf.SaveAs("signed.pdf")
$vbLabelText   $csharpLabel

Output

Add Digital Signature Topdf In Csharp Using Itextsharp 4 related to 3. Digitally Sign PDFs in C# Using IronPDF

4. Explanation of Code

  • IronPDF keeps the signing process simple and readable. You load a PDF, provide a certificate, and call SignPdf(). Optional metadata (contact, location, reason) adds professionalism.

  • iTextSharp gives more control but requires detailed setup with hash algorithms, streams, and certificate chains.

Summary: With just a few lines of code, IronPDF makes it incredibly easy to apply digital signatures using standard .pfx certificates — no low-level cryptography required. This makes it easier to implement when compared to the more lengthy code required by libraries such as iTextSharp to handle the same task.

5. Real-World Use Cases

  • Legal Teams: Automatically sign contracts as they’re generated from templates.

  • Finance: Digitally sign invoices and reports to prevent tampering.

  • Government Portals: Sign forms before submission to meet regulatory standards.

Best Practices for Digital Signatures

To get the most from your digital signing implementation:

  • Use Strong Certificates: Choose 2048-bit RSA keys or stronger.

  • Keep Private Keys Safe: Store certificates securely, ideally in a hardware security module (HSM).

  • Timestamp Your Signatures: Add a trusted timestamp to ensure the signature remains valid even after the certificate expires.

  • Verify Signatures: Include validation in your application to detect tampering or expired certs.

  • Automate: Schedule signing operations in your deployment pipeline for consistent document integrity.

Conclusion

Adding digital signatures to PDF documents is no longer a luxury—it’s a necessity in today’s security-conscious digital landscape. Whether you’re protecting contracts, invoices, reports, or legal documents, having a tamper-evident signature backed by a trusted certificate ensures your files maintain their authenticity and integrity.

In this article, we explored two powerful approaches to PDF signing in C#:

  • iTextSharp, which gives you low-level cryptographic control and flexibility but requires more boilerplate and familiarity with BouncyCastle.

  • IronPDF, which offers a modern, high-level API that makes the process of applying secure signatures seamless and developer-friendly.

Both tools support secure .pfx certificates, but IronPDF clearly simplifies the workflow—ideal for .NET developers who want to spend less time handling cryptographic primitives and more time delivering business value.

iTextSharp vs IronPDF comparison chart

Next Steps

If you haven't already, consider downloading a free trial of IronPDF and try signing your own PDFs in just a few lines of code. The productivity gains alone are worth the switch, especially when working on time-sensitive projects.

Chipego
Software Engineer
Chipego has a natural skill for listening that helps him to comprehend customer issues, and offer intelligent solutions. He joined the Iron Software team in 2023, after studying a Bachelor of Science in Information Technology. IronPDF and IronOCR are the two products Chipego has been focusing on, but his knowledge of all products is growing daily, as he finds new ways to support customers. He enjoys how collaborative life is at Iron Software, with team members from across the company bringing their varied experience to contribute to effective, innovative solutions. When Chipego is away from his desk, he can often be found enjoying a good book or playing football.
< PREVIOUS
A Comparison Between Wkhtmltopdf in Windows & IronPDF
NEXT >
A Comparison between IronPDF and ExpertPDF for .NET