2016-06-15 386 views
0

我正在尝试对任何给定pdf的每个页面进行数字签名。但它只在第一页或最后一页签字。我想我已经知道问题出在MakeSignature.SignDetached()方法。此方法关闭所有流并关闭pdf以进行进一步签名。如何在没有MakeSignature.SignDetached()方法的情况下对pdf进行数字签名?

我的代码:

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); 
      } 
     } 

我使用iTextSharp的库。有没有解决这个问题的方法?

+0

严格地说,“[如何使用iText在所有文档的页面中显示数字PDF签名](http://stackoverflow.com/a/35724742/1729265)”是关于iText,而不是iTextSharp,但来自那里的参数保持一致。 – mkl

+0

谢谢@mkl,我不知道同比对所有论点做了概述。我刚刚提出了它。 –

+0

@furiousNoob *此方法关闭所有流并关闭pdf以进行进一步签名。* - 如果您已经意识到集成PDF签名的问题,请选择“多个签名(每页一个),每个单独一个可视化文件”我引用的答案,现在有实施困难,请相应更新您的问题。它最终会重新打开并回答。 – mkl

回答

0

没有“在PDF中标记每一页”之类的东西。数字签名(可见或不可见)在整个文档上签名。

“签名页面”的概念在PDF中不存在。

如果您使用可见签名,则可以在PDF中的页面上放置小部件注释。一个签名只能对应一个页面上的一个窗口小部件注释。

阅读ISO-32000-1时可能并不明确,但在ISO-32000-2中已明确说明。

总之:没有答案,因为你的问题是错的。您使用该签名的小部件注释混淆了数字签名(可能不可见,签署完整文档:所有页面,所有附件,所有元数据)。

PS:此消息由位于柏林的the PDF Days生效。在一个半小时内(在柏林11:45),您可以关注iText工程师为您提供的这个主题的直播。请参见https://twitter.com/iText/status/742975159976493056

+0

*您可以关注直播视频* - 哎呀,我不知道直播视频。只是在这里打开它,thanx。 ;) – mkl

+0

我在昨天的演讲中提到过你:在SO(3枚金牌)上有3位PDF大师。其中2个是在柏林的PDF日。我们想念你... –