【问题标题】:ITextSharp signing PDF/A documentITextSharp 签署 PDF/A 文档
【发布时间】:2016-01-21 13:08:23
【问题描述】:

所以我正在尝试签署一份 PDF/A-1A 文档,该文档是使用 ITextSharp 生成的。当我签署文件并尝试验证文件时,我收到以下错误,

验证文件“test_pdfA_compliance_signed.pdf”的一致性级别 pdfa-1a 缺少所需的 XMP 属性“pdfaid:part”。 缺少所需的 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 压模的代码,但这是它失败的地方,因为我使用的文档对于我用来确定 PDF/A 声明的两个组件都返回 null,

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

我是在做一些愚蠢的事情还是错过了一些小事? 感谢您的帮助。

亲切的问候

【问题讨论】:

  • 考虑使用 PDF/A 特定的 iTextSharp 类,例如 PdfAStamper。您可能需要添加对 PDF/A 相关 iTextSharp 配套库的依赖项。
  • 我确实使用了 PDF/A 特定类,问题在于 PdfAStamper 抛出异常,指出它不是我试图加载的 PDF/A 文档。我调查了原因,在代码示例中 pdfaidConformance 以及 pdfaidpart 为空。

标签: c# pdf itextsharp itext pdfa


【解决方案1】:

当使用常规的PdfStamper 时,iTextSharp 不会尝试使您的输出文件符合 PDF/A 标准。特别是,它不会添加任何与 PDF/A 相关的元数据。因此,预计您对元数据 (CreatePdfStamperIsPDFADocument()) 的测试将为签名文档返回 false

在您的输入文件上运行该代码示例时,它返回true,其中pdfaidPart 等于1pdfaidConformance 等于A。这是调试器在运行代码时显示的内容:

要获得 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);

【讨论】:

  • 嗯,这真的很奇怪,对我来说,它为两个组件返回 null,即 pdfaidPart 和 pdfaidConformance。所以我正在使用 PDFAStamper 并使用相关代码 sn-p 更新了问题。从代码 sn-p 中,您可以看到我检查它是否是 PDF/A 文档,它使用 PDFAStamper,否则使用普通压模,但对我来说,if 语句失败,这是我的问题所在。由于 5.5.7 中的签名错误,我正在使用 ITextSharp 5.5.6
  • 我已经使用您的确切代码示例、您的 预签名 PDF 和 iTextSharp 5.5.6 再次进行了测试。行为仍如预期。我将使用调试器屏幕截图更新我的答案。
  • 我不知道我的 VisualStudio 在做什么,但今天当我运行与昨天完全相同的代码时,代码按预期工作,我得到了和你一样的结果。唯一的区别是我重新启动了我的 VS,不知道那里发生了什么:O.感谢您的回复和帮助 :)
猜你喜欢
  • 2011-01-22
  • 1970-01-01
  • 2019-02-19
  • 2018-02-24
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
相关资源
最近更新 更多