Digital signature of a PDF with C Sharp and itext

2

In my work they use digital signatures to validate PDF files that are then delivered to those who request them (those who do not belong to the company), so the PDF should show the signature with the data of the signatory.

The signature is being made with the Adobe assistant and using digital signature tokens installed on the computer.

The people who have to sign sign close to 200 PDF per day, so I am developing a desktop application in C # that allows me to sign all the PDFs at once, since with Adobe they have to open the PDF, create a signature field, put the key of the token and just appear the signature, this multiplied by 100 or 200 according to the day. From what I was investigating, it can be done.

What I have so far is a button that opens a dialog that allows you to select all the PDFs to sign. Then another button that opens the Windows certificate store to select the certificate to sign. But I can not create a field and insert the signature, previously asking for the token key.

////Con el método de abajo abro el almacén de certificados y selecciono uno para firmar.

private void btnExplorar_Click(object sender, EventArgs e)
    {
        X509Store store= new X509Store(StoreName.My,StoreLocation.CurrentUser);


        store.Open(OpenFlags.ReadOnly);

        X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
        X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);

        X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Lista de Certificados digitales instalados en su equipo", "Seleccion el certificado con el que desea firmar", X509SelectionFlag.SingleSelection);
        //  X509Certificate2 certificadoElegido = scollection[0];

        if (scollection.Count > 0)
        {

          certificadoElegido = scollection[0];//certificadoElegido es vble de clase

    }

//Con este método recorro un listbox con la lista de todos los PDF seleccionados para firmar e intento crear un campo, pero no sé como lograr que ese campo se cree en el PDF y hacer la firma. Necesito por supuesto que esa firma se vea luego en el PDF para que los solicitantes sepan quién se los firmó.

private void button1_Click(object sender, EventArgs e)
    {
        if (cLBoxListadePdf.CheckedItems.Count!=0) {
            string pdfAFirmar;
            int i;
            for (i=0;i<=cLBoxListadePdf.CheckedItems.Count-1;i++) {
                pdfAFirmar = cLBoxListadePdf.CheckedItems[i].ToString();

                PdfReader pdf = new PdfReader(pdfAFirmar);
                PdfStamper stamper = PdfStamper.CreateSignature(pdf,new FileStream("C:\Users\...", FileMode.Create), '
////Con el método de abajo abro el almacén de certificados y selecciono uno para firmar.

private void btnExplorar_Click(object sender, EventArgs e)
    {
        X509Store store= new X509Store(StoreName.My,StoreLocation.CurrentUser);


        store.Open(OpenFlags.ReadOnly);

        X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
        X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);

        X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Lista de Certificados digitales instalados en su equipo", "Seleccion el certificado con el que desea firmar", X509SelectionFlag.SingleSelection);
        //  X509Certificate2 certificadoElegido = scollection[0];

        if (scollection.Count > 0)
        {

          certificadoElegido = scollection[0];//certificadoElegido es vble de clase

    }

//Con este método recorro un listbox con la lista de todos los PDF seleccionados para firmar e intento crear un campo, pero no sé como lograr que ese campo se cree en el PDF y hacer la firma. Necesito por supuesto que esa firma se vea luego en el PDF para que los solicitantes sepan quién se los firmó.

private void button1_Click(object sender, EventArgs e)
    {
        if (cLBoxListadePdf.CheckedItems.Count!=0) {
            string pdfAFirmar;
            int i;
            for (i=0;i<=cLBoxListadePdf.CheckedItems.Count-1;i++) {
                pdfAFirmar = cLBoxListadePdf.CheckedItems[i].ToString();

                PdfReader pdf = new PdfReader(pdfAFirmar);
                PdfStamper stamper = PdfStamper.CreateSignature(pdf,new FileStream("C:\Users\...", FileMode.Create), '%pre%');
                PdfSignatureAppearance sap = stamper.SignatureAppearance;
                sap.Reason = "";
                //sap.Location=100;
                stamper.Close();
            }
        }
    }
'); PdfSignatureAppearance sap = stamper.SignatureAppearance; sap.Reason = ""; //sap.Location=100; stamper.Close(); } } }

Any suggestions on how to complete this work is welcome.

    
asked by Patricio 03.03.2017 в 15:49
source

1 answer

2

The code I use to sign PDF with itextsharp is the following, I hope it works for you.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;

using Org.BouncyCastle.X509;

using SysX509 = System.Security.Cryptography.X509Certificates;


namespace FirmaPDF
{
    public class firma
    {

        /// <summary>
        /// Firma un documento PDF
        /// </summary>
        /// <param name="Source">Path del PDF a firmar</param>
        /// <param name="Target">Path del PDF firmado</param>
        /// <param name="Certificate">Certificado para realizar la firma</param>
        /// <param name="Reason">Motivo</param>
        /// <param name="Location">Ubicación</param>
        /// <param name="AddVisibleSign">Indica si la firma es visible dentro del documento</param>
        /// <param name="AddTimeStamp">Indica si se va a añadir sello de tiempo en el documento</param>
        /// <param name="strTSA">TSA del sello de tiempo</param>

        public static void SignHashed(string Source, string Target, SysX509.X509Certificate2 Certificate, string Reason, string Location, bool AddVisibleSign, bool AddTimeStamp, string strTSA)
        {
            X509CertificateParser objCP = new X509CertificateParser();
            X509Certificate[] objChain = new X509Certificate[] { objCP.ReadCertificate(Certificate.RawData) };

            IList<ICrlClient> crlList = new List<ICrlClient>();
            crlList.Add(new CrlClientOnline(objChain));

            PdfReader objReader = new PdfReader(Source);
            PdfStamper objStamper = PdfStamper.CreateSignature(objReader, new FileStream(Target, FileMode.Create), '
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;

using Org.BouncyCastle.X509;

using SysX509 = System.Security.Cryptography.X509Certificates;


namespace FirmaPDF
{
    public class firma
    {

        /// <summary>
        /// Firma un documento PDF
        /// </summary>
        /// <param name="Source">Path del PDF a firmar</param>
        /// <param name="Target">Path del PDF firmado</param>
        /// <param name="Certificate">Certificado para realizar la firma</param>
        /// <param name="Reason">Motivo</param>
        /// <param name="Location">Ubicación</param>
        /// <param name="AddVisibleSign">Indica si la firma es visible dentro del documento</param>
        /// <param name="AddTimeStamp">Indica si se va a añadir sello de tiempo en el documento</param>
        /// <param name="strTSA">TSA del sello de tiempo</param>

        public static void SignHashed(string Source, string Target, SysX509.X509Certificate2 Certificate, string Reason, string Location, bool AddVisibleSign, bool AddTimeStamp, string strTSA)
        {
            X509CertificateParser objCP = new X509CertificateParser();
            X509Certificate[] objChain = new X509Certificate[] { objCP.ReadCertificate(Certificate.RawData) };

            IList<ICrlClient> crlList = new List<ICrlClient>();
            crlList.Add(new CrlClientOnline(objChain));

            PdfReader objReader = new PdfReader(Source);
            PdfStamper objStamper = PdfStamper.CreateSignature(objReader, new FileStream(Target, FileMode.Create), '%pre%',null,true);

            // Creamos la apariencia
            PdfSignatureAppearance signatureAppearance = objStamper.SignatureAppearance;
            signatureAppearance.Reason = Reason;
            signatureAppearance.Location = Location;

            // Si está la firma visible:
            if (AddVisibleSign)
                signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 300, 200), 1, null); //signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 250, 150), objReader.NumberOfPages, "Signature");

            ITSAClient tsaClient = null;
            IOcspClient ocspClient = null;

            // Si se ha añadido el sello de tiempo
            if (AddTimeStamp){
                ocspClient = new OcspClientBouncyCastle();
                tsaClient = new TSAClientBouncyCastle(strTSA);
            }

            // Creating the signature
            IExternalSignature externalSignature = new X509Certificate2Signature(Certificate, "SHA-1");
            MakeSignature.SignDetached(signatureAppearance, externalSignature, objChain, crlList, ocspClient, tsaClient, 0, CryptoStandard.CMS);

            if (objReader != null)
                objReader.Close();
            if (objStamper != null)
                objStamper.Close();
        }
    }
}
',null,true); // Creamos la apariencia PdfSignatureAppearance signatureAppearance = objStamper.SignatureAppearance; signatureAppearance.Reason = Reason; signatureAppearance.Location = Location; // Si está la firma visible: if (AddVisibleSign) signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 300, 200), 1, null); //signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 250, 150), objReader.NumberOfPages, "Signature"); ITSAClient tsaClient = null; IOcspClient ocspClient = null; // Si se ha añadido el sello de tiempo if (AddTimeStamp){ ocspClient = new OcspClientBouncyCastle(); tsaClient = new TSAClientBouncyCastle(strTSA); } // Creating the signature IExternalSignature externalSignature = new X509Certificate2Signature(Certificate, "SHA-1"); MakeSignature.SignDetached(signatureAppearance, externalSignature, objChain, crlList, ocspClient, tsaClient, 0, CryptoStandard.CMS); if (objReader != null) objReader.Close(); if (objStamper != null) objStamper.Close(); } } }
    
answered by 13.06.2017 в 13:54