ITextSharp подписание PDF / A документа


Итак, я пытаюсь подписать документ PDF/A-1A, документ был сгенерирован с помощью ITextSharp. Когда я подписываю документ и пытаюсь проверить документ, я получаю следующие ошибки,

Проверка файла " test_pdfA_compliance_signed.pdf " для уровня соответствия pdfa-1a Pdfaid необходимые ХМР недвижимости:часть отсутствует. Pdfaid необходимые ХМР недвижимости:соответствие отсутствует. Длина строки превышает 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 stamper использовать, но это место, где он терпит неудачу, так как документ im using возвращает null для обоих компонентов, которые я использую для определения PDF / a claim,

        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 2

1 ответ:

При использовании обычного PdfStamper iTextSharp не пытается сделать ваш выходной файл PDF/A совместимым. В частности, он не будет добавлять никаких связанных метаданных PDF/A. Поэтому ожидается, что ваш тест на метаданные (CreatePdfStamperIsPDFADocument()) возвращает false для подписанного документа.

При выполнении этого примера кода во входном файле он возвращает true, причем pdfaidPart равно 1 и pdfaidConformance равно A. Это то, что отладчик показывает во время выполнения код:

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