C# ITextSharp签署PDF/A文件

C# ITextSharp签署PDF/A文件,c#,pdf,itextsharp,itext,pdfa,C#,Pdf,Itextsharp,Itext,Pdfa,因此,我试图签署一份PDF/a-1A文件,该文件是使用ITextSharp生成的。当我签署文档并尝试验证文档时,我发现以下错误: 验证符合性级别pdfA-1a的文件“测试pdfA符合性签名.pdf” 缺少必需的XMP属性“pdfaid:part”。 缺少必需的XMP属性“pdfaid:一致性”。 字符串长度超过65535字节。 该文件不符合要求的标准。 文档不符合PDF参考(缺少必需的条目、错误的值类型等)。 文档的元数据缺失、不一致或损坏。 完成了 预先签署的文件: 签署后的文件: 但签名过程

因此,我试图签署一份PDF/a-1A文件,该文件是使用ITextSharp生成的。当我签署文档并尝试验证文档时,我发现以下错误:

验证符合性级别pdfA-1a的文件“测试pdfA符合性签名.pdf” 缺少必需的XMP属性“pdfaid:part”。 缺少必需的XMP属性“pdfaid:一致性”。 字符串长度超过65535字节。 该文件不符合要求的标准。 文档不符合PDF参考(缺少必需的条目、错误的值类型等)。 文档的元数据缺失、不一致或损坏。 完成了

预先签署的文件:

签署后的文件:

但签名过程如期完成,但我意识到,如果我测试文档是否声称符合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;
    }
我是在做傻事还是错过了一些小事? 谢谢你的帮助


亲切问候

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

在输入文件上运行该代码示例时,它返回
true
,其中
pdfaidPart
等于
1
,而
pdfaidcompliance
等于
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);

考虑使用PDF/A特定的TestExcel类,如<代码> PdfAStamper < /代码>。您可能需要在与PDF/a相关的iTextSharp companion库中添加依赖项。我确实使用PDF/a特定的类,问题是PdfAStamper会抛出一个异常,声明我尝试加载的不是PDF/a文档。我调查了原因,在代码示例中,pdfaidcompliance和pdfaidpart都是null.mmm,这真的很奇怪,对我来说,这两个组件(即pdfaidpart和pdfaidcompliance)都返回null。所以我使用PDFAStamper,我用相关的代码片段更新了这个问题。从代码片段中,您可以看到,我检查了如果是PDF/a文档,它是否使用PDFAStamper,否则使用普通母版,但对于我来说,if语句失败,这就是我的问题所在。由于5.5.7中的签名错误,我正在使用ITextSharp 5.5.6。我已使用您的精确代码示例、预签名PDF和ITextSharp 5.5.6再次进行了测试。行为仍如预期。我将用调试器屏幕截图更新我的答案。我不知道我的VisualStudio在做什么,但今天当我运行与昨天完全相同的代码时,代码按预期工作,我得到了与您相同的结果。唯一不同的是我重新启动了我的VS,不知道那里发生了什么:O。感谢您的回复和帮助:)
PdfStamper stamper = PdfAStamper.CreateSignature(reader, outputfile,
    '\0', PdfAConformanceLevel.PDF_A_1A);