As you know, ITextSharp is a library that allows you to create pdf files without installing third party software in your computer. In this post, I'll show you how to put a digital signature in PDF using iTextSharp with C#.

You should install ITextSharp from Nuget Package Manager to your project or you can download it directly from https://github.com/itext/itextsharp, then add a reference to itextsharp.dll

public static void SignPdfFile(string sourceDocument, string destinationPath, Stream privateKeyStream, string password, string reason, string location)
{
    Pkcs12Store pk12 = new Pkcs12Store(privateKeyStream, password.ToCharArray());
    privateKeyStream.Dispose();
    string alias = null;
    foreach (string tAlias in pk12.Aliases)
    {
        if (pk12.IsKeyEntry(tAlias))
        {
            alias = tAlias;
            break;
        }
    }
    var pk = pk12.GetKey(alias).Key;
    iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(sourceDocument);
    using (FileStream fout = new FileStream(destinationPath, FileMode.Create, FileAccess.ReadWrite))
    {
        using (iTextSharp.text.pdf.PdfStamper stamper = iTextSharp.text.pdf.PdfStamper.CreateSignature(reader, fout, '\0'))
        {
            iTextSharp.text.pdf.PdfSignatureAppearance appearance = stamper.SignatureAppearance;
            iTextSharp.text.pdf.BaseFont bf = iTextSharp.text.pdf.BaseFont.CreateFont(System.Web.HttpContext.Current.Server.MapPath("~/Content/fonts/Arial.ttf"), iTextSharp.text.pdf.BaseFont.IDENTITY_H, iTextSharp.text.pdf.BaseFont.EMBEDDED);
            iTextSharp.text.Font font = new iTextSharp.text.Font(bf, 11);
            appearance.Layer2Font = font;
            //appearance.Image = new iTextSharp.text.pdf.PdfImage();
            appearance.Reason = reason;
            appearance.Location = location;
            appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(20, 10, 170, 60), 1, "Icsi-Vendor");
            iTextSharp.text.pdf.security.IExternalSignature es = new iTextSharp.text.pdf.security.PrivateKeySignature(pk, "SHA-256");
            iTextSharp.text.pdf.security.MakeSignature.SignDetached(appearance, es, new X509Certificate[] { pk12.GetCertificate(alias).Certificate }, null, null, null, 0, iTextSharp.text.pdf.security.CryptoStandard.CMS);
            stamper.Close();
        }
    }
}

You should add unicode fonts when adding a digital signature if you don't want to lose fonts. To call the function above, you need to read the pfx extension file into the stream, then embed the degital signature into the pdf file. To get the pfx extension file, you can export your certificate from the operating system.

string sourceDocument = filePath;
string destinationPath = filePath.Replace(".pdf", "_signed.pdf");
Stream stream = File.OpenRead(HttpContext.Current.Server.MapPath($"~/bin/Signatures/{fileName}"));
PdfSign.SignPdfFile(sourceDocument, destinationPath, stream, invoice.Password, reason, location);