Quantcast
Channel: Signing existing PDF document sometimes causes a corrupt file - Stack Overflow
Viewing all articles
Browse latest Browse all 2

Signing existing PDF document sometimes causes a corrupt file

$
0
0

I am writing a demo proof of concept to add electronic signatures to existing PDFs. I am running into one weird problem that I don't get. It seems that adding the signature to some documents works fine while adding one to others does not work and a corrupt file is generated that Adobe Reader can not open.

Here is my code:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using iText;using iText.Kernel.Pdf;using System.IO;using iText.Layout;using iText.Layout.Element;using iText.Kernel.Geom;using Org.BouncyCastle.Crypto.Tls;using iText.Signatures;using System.Collections.ObjectModel;using Org.BouncyCastle.Pkcs;using System.Security.Cryptography.X509Certificates;using Org.BouncyCastle.Crypto;using System.Security.Cryptography;using Org.BouncyCastle.Crypto.Parameters;using Org.BouncyCastle.Math;using iText.IO.Image;namespace LTVSkilrikjaDemo{    class Program    {        static void Main(string[] args)        {            string welcomeText = "Welcome to LTVSkilríkjaDemotolid!";            string pressEnterToTry = "Commands: 's' - sign, 'stop' - stops the programme";            Console.WriteLine(welcomeText);            Console.WriteLine(pressEnterToTry);            // Base directory prepared            string basedir = AppDomain.CurrentDomain.BaseDirectory;            int index = basedir.IndexOf(@"bin\");            basedir = basedir.Remove(index);            string readString = Console.ReadLine().ToLower();            while(!readString.Equals("stop"))            {                if(readString.Equals("c"))                {                    string inFile = "Infile2.pdf";                    string outFile = "Outfile2.pdf";                    // Open PDF document and decide where to write the new document                    PdfWorker worker = new PdfWorker();                    worker.ReadPdf(basedir +"App_Data\\InFiles\\"+ inFile, basedir +"App_Data\\OutFiles\\"+ outFile);                    // Start working on certificate                    X509Store store = new X509Store("My");                    store.Open(OpenFlags.ReadOnly);                    Collection<Org.BouncyCastle.X509.X509Certificate> xcertificates = new Collection<Org.BouncyCastle.X509.X509Certificate>();                    foreach (X509Certificate2 mCert in store.Certificates)                    {                        if (mCert.Subject.IndexOf("CN=Róbert") > -1)                        {                             xcertificates.Add(Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(mCert));                        }                    }                    Org.BouncyCastle.X509.X509Certificate[] certificatesProcessed = new Org.BouncyCastle.X509.X509Certificate[xcertificates.Count];                    for(int i = 0; i < xcertificates.Count; i++)                    {                        certificatesProcessed[i] = xcertificates[i];                    }                    var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(store.Certificates[5].PrivateKey).Private;                    try                    {                        worker.Sign(certificatesProcessed, pk, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CADES, "No apparent raisin!", "Lost in Iceland", null, null, null, 0, true, basedir);                    }                    catch(Exception ex)                    {                        Console.ForegroundColor = ConsoleColor.Red;                        Console.WriteLine("Error! "+ ex.Message +"\n\r"+ ex.StackTrace);                        if(ex.InnerException != null)                        {                            Console.WriteLine("Inner exception: "+ ex.InnerException.Message);                        }                        Console.ForegroundColor = ConsoleColor.Gray;                                          }                }                else if(!readString.Equals("stop"))                {                    Console.WriteLine("Command not understood. Understand only 's' and 'stop'.");                }                readString = Console.ReadLine();            }            Console.WriteLine("Goodbye!");            System.Threading.Thread.Sleep(500);        }    }    public class PdfWorker    {        private PdfDocument _document;        private string _source;        private string _dest;        public void ReadPdf(string source, string dest)        {            _source = source;            _dest = dest;        }        public void Sign(Org.BouncyCastle.X509.X509Certificate[] chain, Org.BouncyCastle.Crypto.ICipherParameters pk,            string digestAlgorithm, PdfSigner.CryptoStandard subfilter, string reason,             string location, Collection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,            int estimatedSize, bool initial, string baseDir)        {            File.Copy(_source, _dest, true);            FileStream f = new FileStream(_dest, FileMode.Append);            try            {                PdfSigner signer = new PdfSigner(new PdfReader(_source), f, true);                _document = signer.GetDocument();                _document.AddNewPage();                // Work the last page                Rectangle pageSize = _document.GetLastPage().GetPageSizeWithRotation();                //PdfWriter w = _document.GetWriter();                //long currentPos = w.GetCurrentPos();                float llx = pageSize.GetWidth() - 350 - 20; //pageSize.GetWidth() / 2 - 350 / 2;                float lly = pageSize.GetHeight() - 50 - 20; // pageSize.GetHeight() / 2 - 150 / 2;                float urx = 350; //llx + 350;                float ury = 50; //lly + 150;                PdfSignatureAppearance appearance = signer.GetSignatureAppearance();                appearance.SetPageRect(new Rectangle(llx, lly, urx, ury));                appearance.SetReason(reason);                appearance.SetLocation(location);                byte[] imagebytes = File.ReadAllBytes(baseDir +"App_Data\\UndirskriftDemo.png");                // It is not possible to use the path as it contains Icelandic characters                 // which itext chokes on. We use byte array instead                ImageData imgData = ImageDataFactory.Create(imagebytes);                Image img = new Image(imgData);                img = img.ScaleToFit(350.0f, 50.0f);                appearance.SetImage(imgData);                int pageCount = _document.GetNumberOfPages();                // Creating the appearance                if(initial == true)                {                    signer.SetCertificationLevel(PdfSigner.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);                }                appearance.SetPageNumber(pageCount);                Rectangle rect = new Rectangle(10, 50, 350, 50);                appearance.SetPageRect(rect).SetPageNumber(pageCount);                appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);                signer.SetFieldName(signer.GetNewSigFieldName());                // Creating the signature            IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);                signer.SignDetached(pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);                Console.WriteLine("Signing successful!");            }            catch(Exception ex)            {                throw ex;            }            finally            {                _document.Close();                f.Close();            }        }    }}

Please see the documents here then. Infile1.pdf I can not sign but Infile2.pdf is signed fine. Outfile1.pdf is the corrupt file.https://app.box.com/s/52jqe8qirl80km6hunxucs00dntx70o5

What causes this? Is there something about the input PDF file or the above programme?


Viewing all articles
Browse latest Browse all 2

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>