2

所以我正在尝试签署一份 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);
        }
    }

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

亲切的问候

4

1 回答 1

2

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

在您的输入文件上运行该代码示例时,它会返回、true、和。这是调试器在运行代码时显示的内容:pdfaidPart1pdfaidConformanceA

pdfaid 价值观

要获得 PDF/A 输出文件,您必须使用PdfAStamper. 你说这PdfAStamper会给你一个关于你的输入文件不是 PDF/A 的错误。这可能是因为您指定的 PDF/A 部分和/或一致性级别与输入文件不同。PdfAStamper不会将 PDF/A 输入文件转换为不同的部分或一致性级别。

因此,请确保PdfAStamper为 PDF/A-1a 输入创建:

PdfStamper stamper = PdfAStamper.CreateSignature(reader, outputfile,
    '\0', PdfAConformanceLevel.PDF_A_1A);
于 2015-10-22T17:15:21.383 回答