0

I am trying to digitally sign every pages of any given pdf. But it only signs in first or last page. I think I have figure out that the issues is in MakeSignature.SignDetached() method. This method closes all the stream and closes the pdf for further signing.

My code:

 public static void SignInForEveryPage(string input, string output, PDFEncryption pdfEnc, bool encrypt, bool passCheck, string pass) {
            X509CertificateParser cp = new X509CertificateParser();
            X509Certificate[] chain = { cp.ReadCertificate(CertInfo.MyCert.RawData) };

            IExternalSignature externalSignature = new X509Certificate2Signature(CertInfo.MyCert, "SHA-1");
            //Setup signature
            if(File.Exists(output)) {
                File.Delete(output);
            }
            PdfSignatureAppearance signatureAppearance=null;
            PdfSignatureAppearance tempAppearance = null;

            PdfReader reader = new PdfReader(input);
            FileStream firstFileStream = new FileStream(output, FileMode.Create, FileAccess.ReadWrite);
            PdfStamper pdfStamper = PdfStamper.CreateSignature(reader, firstFileStream, '\0', null, true);

            for(int index = 1; index <= reader.NumberOfPages; index++) {
                if(encrypt && pdfEnc != null) {
                    pdfEnc.Encrypt(pdfStamper);
                }
                if(passCheck) {
                    pdfStamper.SetEncryption(PdfWriter.STRENGTH128BITS, "123", "123", PdfWriter.ALLOW_COPY);
                    //Set password of output file
                }

                //Write the metadata
                pdfStamper.MoreInfo = MetaData.GetMetaData();
                pdfStamper.XmpMetadata = MetaData.GetStreamedMetaData();

                //Set signature appearance
                 signatureAppearance = pdfStamper.SignatureAppearance;
                signatureAppearance.Reason = ReasonText; //Reason
                signatureAppearance.Contact = ContactText; //Contact
                signatureAppearance.Location = LocationText; //Location

                byte[] rawData = null;
                var customText = "";

                //Set the text shown in signature
                customText += "Digitally Signed by:\n";
                customText += CertInfo.CertName + "\n";

                if(!string.IsNullOrEmpty(LocationText)) {
                    customText += "Location: ";
                    customText += LocationText + "\n";
                }

                if(!string.IsNullOrEmpty(ReasonText)) {
                    customText += "Reason: ";
                    customText += ReasonText + "\n";
                }

                customText += "Date: ";
                customText += DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss K") + "\n";
                customText = customText.TrimEnd();

                //set the image shown in signature
                if(ShowImage && SignaturePictureImage != null) {
                    using(MemoryStream memoryStream = new MemoryStream()) {
                        SignaturePictureImage.Save(memoryStream, ImageFormat.Bmp);
                        rawData = memoryStream.ToArray();
                    }
                }

                //For signature position and size
                var sigX = Mm2Pt(LeftNumValue);
                var sigY = Mm2Pt(BottomNumValue);
                var sigW = Mm2Pt(WidthNumValue);
                var sigH = Mm2Pt(HeightNumValue);

                //Draw the rectangle for signature field
                //pdfStamper.Reader.GetPageSize(index);
                signatureAppearance.SignatureGraphic = rawData == null ? null : iTextSharp.text.Image.GetInstance(rawData);
                signatureAppearance.Layer2Text = customText;
                signatureAppearance.Layer4Text = ""; //if null or not set then it will show 'signature not valid'
                signatureAppearance.Acro6Layers = true;
                if(signatureAppearance.SignatureGraphic != null) {
                    signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;
                    //show image first then text in the signature
                }
                signatureAppearance.SetVisibleSignature(new Rectangle(sigX, sigY, sigX + sigW, sigY + sigH), index, null);
                signatureAppearance.GetLayer(1);
                tempAppearance = signatureAppearance;
                MakeSignature.SignDetached(tempAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
            }
        }

I am using iTextSharp library. Is there any way of fixing this code?

furiousNoob
  • 53
  • 5
  • 16
  • Strictly speaking "[How to show digital PDF signature in all document's Page using iText](http://stackoverflow.com/a/35724742/1729265)" is about iText, not iTextSharp, but the arguments from there hold identically. – mkl Jun 15 '16 at 07:17
  • Thanks @mkl, I didn't know yoy had made an overview of all the arguments. I just upvoted it. – Bruno Lowagie Jun 15 '16 at 07:20
  • @furiousNoob *This method closes all the stream and closes the pdf for further signing.* - if you already were aware of the issues of integrated PDF signatures, chose the "Multiple signatures (one per page) with a single visualization each" from the answer I referenced, and now have implementation difficulties, please update your question accordingly. It will eventually be re-opened and answered. – mkl Jun 15 '16 at 08:35

1 Answers1

0

There is no such thing as "sign every page in a PDF." A digital signature (either visible or invisible) signs the complete document.

The concept of "signing a page" simply doesn't exist in PDF.

If you use a visible signature, you put a widget annotation on a page in the PDF. One signature can correspond with only one widget annotation on only one page.

This may not be clear when reading ISO-32000-1, but it is made explicitly clear in ISO-32000-2.

In short: there is no answer to your question because your question is wrong. You are confusing the digital signature (possibly invisible, signing the full document: all pages, all attachments, all metadata) with the widget annotation of that signature.

PS: this message is brought live from the PDF Days in Berlin. In exactly 1 and a half hour (at 11:45 in Berlin), you can follow a live stream on this subject brought to you by an iText engineer. See https://twitter.com/iText/status/742975159976493056

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • *you can follow a live stream* - oops, I didn't know about the live stream. Just switched it on here, thanx. ;) – mkl Jun 15 '16 at 07:48
  • I mentioned you in my talk yesterday: there are 3 masters of PDF on SO (3 gold medals). 2 out of these 3 are at the PDF Days in Berlin. We were missing you... – Bruno Lowagie Jun 15 '16 at 07:57