Itext 5 - отдельная подпись - переменная byte [], возвращаемая getRangeStream () - PullRequest
0 голосов
/ 11 марта 2019

Я не понимаю, почему inputStream, возвращаемый getRangeStream (), отличается на каждой итерации кода в одном и том же файле.Обычно он должен возвращать «байты документа, которые можно хэшировать при использовании внешних подписей», что для меня означает, что для того же входного файла должен быть возвращен один и тот же байтовый массив.Но это не так ...

PdfReader pdfReader = new PdfReader(new FileInputStream(inPdfFile), null);
    AcroFields acroFields = pdfReader.getAcroFields();
    boolean hasSignature = acroFields.getSignatureNames().size() > 0;
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    PdfStamper pdfStamper = PdfStamper.createSignature(pdfReader, byteArrayOutputStream, '\0', null, hasSignature);
    pdfStamper.setXmpMetadata(pdfReader.getMetadata());

    PdfSignatureAppearance pdfSignatureAppearance = pdfStamper.getSignatureAppearance();
    PdfSignature pdfSignature = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
    pdfSignature.setReason("reason");
    pdfSignature.setLocation("location");
    pdfSignature.setContact("contact");
    pdfSignatureAppearance.setCryptoDictionary(pdfSignature);

    // certify the pdf, if requested
   /* if (certificationLevel > 0) {
        // check: at most one certification per pdf is allowed
        if (pdfReader.getCertificationLevel() != PdfSignatureAppearance.NOT_CERTIFIED)
            throw new Exception("Could not apply -certlevel option. At most one certification per pdf is allowed, but source pdf contained already a certification.");
        pdfSignatureAppearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
    }*/
    pdfSignatureAppearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);

    HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
    exc.put(PdfName.CONTENTS, new Integer(30000 * 2 + 2));

    pdfSignatureAppearance.preClose(exc);

    InputStream rangeStream = pdfSignatureAppearance.getRangeStream();

1 Ответ

1 голос
/ 11 марта 2019

Интегрированная подпись PDF не просто добавляется как есть к существующему PDF, но это значение поля формы подписи (вместе с некоторой метаинформацией).И совместимая такая подпись должна подписывать все, кроме места, зарезервированного для нее в значении поля подписи.

Поэтому всякий раз, когда вы пытаетесь подписать существующий pdf, его обычно нужно подготовить: если в pdf еще нет структуры формы, ее необходимо добавить.Если еще нет пустого поля формы подписи, такое поле формы необходимо добавить.И значение подписи должно быть подготовлено, в частности, со временем подписания.

Всякий раз, когда вы создаете или обновляете файл PDF, создается идентификатор, определяется время создания или изменения, и эти данные добавляются в созданный / обновленный файл PDF.

Таким образом, ваш код при каждом запуске манипулирует исходным PDF-файлом, поэтому полученные PDF-файлы имеют разные идентификаторы, время модификации и время подписания.И поскольку подпись подписывает все, кроме ее заполнителя, она также подписывает эти переменные данные.

Следовательно, хэш различается при каждом запуске.


Для получения более подробной информации прочитайте этот ответ и статьи, на которые есть ссылки.

...