ITextSharp签署PDF / A文档

时间:2015-10-22 09:38:27

标签: c# pdf itextsharp itext pdfa

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

我做了些什么愚蠢或遗失的小事吗? 谢谢你的帮助。

亲切的问候

1 个答案:

答案 0 :(得分:2)

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

在输入文件上运行该代码示例时,它返回truepdfaidPart等于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);