Search Results for

    Show / Hide Table of Contents

    Signing PDFs (C# / netframework)

    Note

    This demo is available in your FlexCel installation at <FlexCel Install Folder>\samples\csharp\VS2022\netframework\25.Printing and Exporting\35.Signing Pdfs and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​NET-​demos/​tree/​master/​csharp/​VS2022/​netframework/​Modules/​25.​Printing and Exporting/35.Signing Pdfs

    Overview

    In this example we will show how to add a visible or invisible signature to a generated PDF file.

    Concepts

    • In order to sign a PDF file you will need a certificate issued by a valid Certificate Authority, or one issued by yourself. In this example we will use a self signed certificate. This certificate will not validate by default when you open it in Acrobat, you need to add it to your trusted list.

    • The default algorithm for CmsSigner .NET class is SHA-1, which is known to have vulnerabilities and shouldn't be used anymore. So in this example we use SHA512 instead by changing the DigestAlgorithm.

    • In order to sign a file, FlexCel will write a requirement for Acrobat 8 or newer in the generated files. This is because only Acrobat 8 or newer support SHA512. Older versions of acrobat will still display the pages but will not validate the signature.

    • We provide a default signing implementation using standard .NET crypto classes. You can still create your own signature engine by using a third party cryptography library or by calling CryptoApi in windows via p/invoke. This is explained in the section Signing PDF Files in the PDF exporting guide.

    Files

    mainForm.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using FlexCel.Render;
    using FlexCel.XlsAdapter;
    using FlexCel.Pdf;
    using System.IO;
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Cryptography.Pkcs;
    using System.Drawing.Imaging;
    using System.Reflection;
    using System.Diagnostics;
    
    namespace SigningPdfs
    {
        public partial class mainForm: Form
        {
            public mainForm()
            {
                Application.EnableVisualStyles();
                InitializeComponent();
            }
    
            private void cbVisibleSignature_CheckedChanged(object sender, EventArgs e)
            {
                SignaturePicture.Visible = cbVisibleSignature.Checked;
                int delta = SignaturePicture.Height + 30;
                if (cbVisibleSignature.Checked) this.Height += delta; else this.Height -= delta;
            }
    
            private void SignaturePicture_Click(object sender, EventArgs e)
            {
                if (OpenImageDialog.ShowDialog() != DialogResult.OK) return;
                SignaturePicture.Load(OpenImageDialog.FileName);
            }
    
            private void btnCreateAndSign_Click(object sender, EventArgs e)
            {
                //Load the Excel file.
                if (OpenExcelDialog.ShowDialog() != DialogResult.OK) return;
                XlsFile xls = new XlsFile();
                xls.Open(OpenExcelDialog.FileName);
    
                string DataPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\..\..\";
    
                //Export it to pdf.
                using (FlexCelPdfExport pdf = new FlexCelPdfExport(xls, true))
                {
                    pdf.FontEmbed = TFontEmbed.Embed;
    
                    //Load the certificate and create a signer.
                    //In this example we just have the password in clear. It should be kept in a SecureString.
                    //Also make sure to set the flag X509KeyStorageFlags.EphemeralKeySet to avoid files created
                    //on disk: https://snede.net/the-most-dangerous-constructor-in-net/
                    //As X509KeyStorageFlags.EphemeralKeySet only exists in .NET 4.8 or newer, for older versions we will 
                    //define it as (X509KeyStorageFlags)32. For .NET 4.8 or newer and  NET Core, you can use X509KeyStorageFlags.EphemeralKeySet
                      X509Certificate2 Cert = new X509Certificate2(DataPath + "flexcel.pfx", "password", X509KeyStorageFlags.EphemeralKeySet);  
    
                    //Note that to use the CmsSigner class you need to add a reference to System.Security dll. 
                    //It is *not* enough to add it to the using clauses, you need to add a reference to the dll.
                    CmsSigner Signer = new CmsSigner(Cert);
    
                    //By default CmsSigner uses SHA1, but SHA1 has known vulnerabilities and it is deprecated. 
                    //So we will use SHA512 instead.
                    //"2.16.840.1.101.3.4.2.3" is the Oid for SHA512.
                    Signer.DigestAlgorithm = new System.Security.Cryptography.Oid("2.16.840.1.101.3.4.2.3");
    
                    TPdfSignature sig;
                    if (cbVisibleSignature.Checked)
                    {
                        using (MemoryStream fs = new MemoryStream())
                        {
                            SignaturePicture.Image.Save(fs, ImageFormat.Png);
                            byte[] ImgData = fs.ToArray();
    
                            //The -1 as "page" parameter means the last page.
                            sig = new TPdfVisibleSignature(new TBuiltInSignerFactory(Signer),
                                "Signature", "I have read the document and certify it is valid.", "Springfield", "adrian@tmssoftware.com", -1, new RectangleF(50, 50, 140, 70), ImgData);
                        }
                    }
                    else
                    {
                        sig = new TPdfSignature(new TBuiltInSignerFactory(Signer),
                                    "Signature", "I have read the document and certify it is valid.", "Springfield", "adrian@tmssoftware.com");
                    }
    
                    //You must sign the document *BEFORE* starting to write it.
                    pdf.Sign(sig);
    
                    if (savePdfDialog.ShowDialog() != DialogResult.OK) return;
                    using (FileStream PdfStream = new FileStream(savePdfDialog.FileName, FileMode.Create))
                    {
                        pdf.BeginExport(PdfStream);
                        pdf.ExportAllVisibleSheets(false, "Signed Pdf");
                        pdf.EndExport();
                    }
    
                }
    
                if (MessageBox.Show("Do you want to open the generated file?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return;
                Process.Start(savePdfDialog.FileName);
    
            }
        }
    }
    

    mainForm.Designer.cs

    namespace SigningPdfs
    {
        partial class mainForm
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.btnCreateAndSign = new System.Windows.Forms.Button();
                this.cbVisibleSignature = new System.Windows.Forms.CheckBox();
                this.OpenExcelDialog = new System.Windows.Forms.OpenFileDialog();
                this.savePdfDialog = new System.Windows.Forms.SaveFileDialog();
                this.SignaturePicture = new System.Windows.Forms.PictureBox();
                this.OpenImageDialog = new System.Windows.Forms.OpenFileDialog();
                ((System.ComponentModel.ISupportInitialize)(this.SignaturePicture)).BeginInit();
                this.SuspendLayout();
                // 
                // btnCreateAndSign
                // 
                this.btnCreateAndSign.Image = global::SigningPdfs.Properties.Resources.acroread;
                this.btnCreateAndSign.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
                this.btnCreateAndSign.Location = new System.Drawing.Point(24, 25);
                this.btnCreateAndSign.Name = "btnCreateAndSign";
                this.btnCreateAndSign.Size = new System.Drawing.Size(155, 30);
                this.btnCreateAndSign.TabIndex = 0;
                this.btnCreateAndSign.Text = "Create and Sign Pdf";
                this.btnCreateAndSign.UseVisualStyleBackColor = true;
                this.btnCreateAndSign.Click += new System.EventHandler(this.btnCreateAndSign_Click);
                // 
                // cbVisibleSignature
                // 
                this.cbVisibleSignature.AutoSize = true;
                this.cbVisibleSignature.Location = new System.Drawing.Point(24, 78);
                this.cbVisibleSignature.Name = "cbVisibleSignature";
                this.cbVisibleSignature.Size = new System.Drawing.Size(167, 17);
                this.cbVisibleSignature.TabIndex = 1;
                this.cbVisibleSignature.Text = "Visible Signature (in last page)";
                this.cbVisibleSignature.UseVisualStyleBackColor = true;
                this.cbVisibleSignature.CheckedChanged += new System.EventHandler(this.cbVisibleSignature_CheckedChanged);
                // 
                // OpenExcelDialog
                // 
                this.OpenExcelDialog.DefaultExt = "xls";
                this.OpenExcelDialog.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm|Excel 97/2003|*.xls|Excel 2007|*.xlsx;*.xlsm|All files|*.*";
                this.OpenExcelDialog.Title = "Select Excel file to convert...";
                // 
                // savePdfDialog
                // 
                this.savePdfDialog.DefaultExt = "pdf";
                this.savePdfDialog.Filter = "Pdf Files|*.pdf";
                this.savePdfDialog.Title = "Select where to save the file...";
                // 
                // SignaturePicture
                // 
                this.SignaturePicture.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
                this.SignaturePicture.Image = global::SigningPdfs.Properties.Resources.sign;
                this.SignaturePicture.Location = new System.Drawing.Point(24, 110);
                this.SignaturePicture.Name = "SignaturePicture";
                this.SignaturePicture.Size = new System.Drawing.Size(155, 100);
                this.SignaturePicture.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
                this.SignaturePicture.TabIndex = 2;
                this.SignaturePicture.TabStop = false;
                this.SignaturePicture.Click += new System.EventHandler(this.SignaturePicture_Click);
                // 
                // OpenImageDialog
                // 
                this.OpenImageDialog.Filter = "Supported Images|*.png;*.bmp*.jpg|All files|*.*";
                // 
                // mainForm
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(205, 100);
                this.Controls.Add(this.SignaturePicture);
                this.Controls.Add(this.cbVisibleSignature);
                this.Controls.Add(this.btnCreateAndSign);
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
                this.Name = "mainForm";
                this.Text = "Signing PDFs";
                ((System.ComponentModel.ISupportInitialize)(this.SignaturePicture)).EndInit();
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
    
            #endregion
    
            private System.Windows.Forms.Button btnCreateAndSign;
            private System.Windows.Forms.CheckBox cbVisibleSignature;
            private System.Windows.Forms.OpenFileDialog OpenExcelDialog;
            private System.Windows.Forms.SaveFileDialog savePdfDialog;
            private System.Windows.Forms.PictureBox SignaturePicture;
            private System.Windows.Forms.OpenFileDialog OpenImageDialog;
        }
    }
    

    Program.cs

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    namespace SigningPdfs
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new mainForm());
            }
        }
    }
    
    In This Article
    Back to top FlexCel Studio for the .NET Framework v7.24.0.0
    © 2002 - 2025 tmssoftware.com