2015-10-22 34 views
2

所以我想簽署一個PDF/A-1A文檔,該文檔是使用ITextSharp生成的。當我在文件上簽名,並嘗試驗證文件我碰到下面的錯誤,ITextSharp簽署PDF/A文檔

驗證文件「test_pdfA_compliance_signed.pdf」一致性水平PDFA-1A 所要求XMP財產「pdfaid:部分」缺失。 缺少必需的XMP屬性'pdfaid:conformance'。 一個字符串長於65535字節。 該文件不符合要求的標準。 該文檔不符合PDF參考(缺少必需的條目,錯誤的值類型等)。 文檔的元數據缺失或不一致或損壞。 完成。

文件預簽名:簽名後https://drive.google.com/file/d/0B9RyqgJoa6W8UDFSeHJSX09QamM/view?usp=sharing

文件:https://drive.google.com/file/d/0B9RyqgJoa6W8Y3lGbFU4a2RsLWc/view?usp=sharing

但按預期的方式完成了簽約過程,但我已經意識到了,如果我測試是否該文件宣稱是PDF/A兼容的,如果沒有元數據聲稱PDF/A失敗,

private bool CreatePdfStamperIsPDFADocument(PdfReader reader) 
    { 
     if (reader.Metadata != null && reader.Metadata.Length > 0) 
     { 
      IXmpMeta xmpMeta = XmpMetaParser.Parse(reader.Metadata, null); 
      IXmpProperty pdfaidConformance = xmpMeta.GetProperty(XmpConst.NS_PDFA_ID, "pdfaid:conformance"); 
      IXmpProperty pdfaidPart = xmpMeta.GetProperty(XmpConst.NS_PDFA_ID, "pdfaid:part"); 

      if (pdfaidConformance == null || pdfaidPart == null) 
      { 
       return false; 
      } 
     } 

     return true; 
    } 

我曾經簽署該文件的代碼,該PDF壓模我們由於檢查失敗,這裏編輯是正常的。當我嘗試使用PDFAStamper時,它抱怨說只能使用PDF/A文檔。

private byte[] SignDocument(Certificate certificate, SigningInformation information, List<SigningBlock> signingBlocks, List<MemberItemSignature> signatureImages, byte[] document, bool certify) 
    { 
     for (int i = 0; i < signingBlocks.Count; i++) 
     { 
      using (MemoryStream outputStream = new MemoryStream()) 
      { 
       using (PdfReader reader = new PdfReader(document)) 
       { 
        using (PdfStamper stamper = CreatePdfStamper(reader, outputStream, true)) 
        { 
         SigningBlock signingBlock = signingBlocks[i]; 
         PdfSignatureAppearance appearance = CreatePdfAppearance(stamper, information, certify && i == 0); 

         SignDocumentSigningBlock(certificate, information, signingBlock, appearance, stamper, GetSignatureImage(signatureImages, signingBlock.Name)); 
        } 
       } 

       document = outputStream.ToArray(); 
      } 
     } 

     return document; 
    } 

因此,這是我決定使用哪個PDF壓模的代碼,但是這是因爲使用的返回null,因爲我用它來確定PDF/A要求兩個組件文檔IM哪裏失敗,

 private PdfStamper CreatePdfStamper(PdfReader reader, MemoryStream outputStream, bool isSignature) 
    { 
     if (isSignature) 
     { 
      if (CreatePdfStamperIsPDFADocument(reader)) 
      { 
       return PdfAStamper.CreateSignature(reader, outputStream, _pdfVersion, null, true, PdfAConformanceLevel.PDF_A_1A); 
      } 
      else 
      { 
       return PdfStamper.CreateSignature(reader, outputStream, _pdfVersion, null, true); 
      } 
     } 
     else 
     { 
      return new PdfStamper(reader, outputStream, _pdfVersion, true); 
     } 
    } 

我在做一些愚蠢的事情或缺少一些小事? 謝謝你的幫助。

親切的問候

+0

考慮使用PDF/A的特定iTextSharp的類,如'PdfAStamper'。您可能必須在PDF/A相關的iTextSharp隨播庫中添加依賴項。 – mkl

+0

我確實使用PDF/A特定類,問題是PdfAStamper拋出一個異常,指出它不是一個試圖加載的PDF/A文檔。我調查了爲什麼,並在代碼示例pdfaidConformance以及pdfaidpart爲null。 – Johandre

回答

2

當使用常規PdfStamper,iTextSharp的不作企圖使你的輸出文件的PDF/A標準。特別是,它不會添加任何PDF/A相關的元數據。因此,預計您對元數據(CreatePdfStamperIsPDFADocument())的測試會爲簽名文檔返回false

當運行在你的輸入文件的代碼示例,它返回true,與pdfaidPart等於1pdfaidConformance等於A。這是調試器顯示在運行代碼:

pdfaid values

爲了得到一個PDF/A輸出文件,你必須使用PdfAStamper。你說PdfAStamper給你一個有關你的輸入文件不是PDF/A的錯誤。這可能是因爲您正在指定與您的輸入文件不同的PDF/A部分和/或一致性級別。 PdfAStamper不會將PDF/A輸入文件轉換爲不同的部件或一致性級別。

因此,請確保您的PDF/A-1A輸入創建PdfAStamper

PdfStamper stamper = PdfAStamper.CreateSignature(reader, outputfile, 
    '\0', PdfAConformanceLevel.PDF_A_1A); 
+0

mmm這真的很奇怪,對我來說,它對兩個組件返回null,即pdfaidPart和pdfaidConformance。所以我正在使用PDFAStamper,並且用相關的代碼片段更新了這個問題。從代碼片段中,你可以看到我做了一個檢查,如果它是PDF/A文檔,它使用PDFAStamper,否則使用正常的壓模,但對於我來說,if語句失敗,這是我的問題。由於5.5.7中的簽名錯誤,我使用ITextSharp 5.5.6 – Johandre

+0

我已經使用您的確切代碼示例,您的* Pre-Signed * PDF和iTextSharp 5.5.6再次進行了測試。行爲仍然如預期。我將用調試器屏幕截圖更新我的答案。 – rhens

+1

我不知道我的VisualStudio做了什麼,但是今天當我運行與昨天完全相同的代碼時,代碼按預期工作,並且我得到了與您一樣的結果。唯一的區別是我重新啓動我的VS,不知道那裏發生了什麼:O.Thanks的反應和幫助:) – Johandre