Цифровая подпись Java PDF с использованием iText видна, но не печатается - PullRequest
0 голосов
/ 07 ноября 2018

Я использую методы iText для подписи PDF с цифровым сертификатом, создавая подпись, видимую в документе с помощью PdfSignatureAppearance, но я бы хотел, чтобы видимая подпись не появлялась в печати. Я видел, что есть нечто подобное в классе PdfAnnotation, где вы можете добавить флаг для этого. Есть ли способ сделать это с цифровой подписью? Мой код:

PdfStamper stp = null;
try {
    PdfReader reader = new PdfReader(pdfInputFileName);

    stp = PdfStamper.createSignature(reader, fout, '\0');
    PdfSignatureAppearance sap = stp.getSignatureAppearance();

    sap.setCrypto(privateKey, certificateChain, null, PdfSignatureAppearance.WINCER_SIGNED);

    sap.setReason(reason);
    sap.setLocation(location);
    sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
    sap.setVisibleSignature(new Rectangle(30, 830, 170, 770), 1, null);

    stp.close();

} catch (DocumentException | IOException e) {

    logger.error("An unknown error accoured while signing the PDF file: " + e.getMessage());
}

Это ссылка на PDF-файл, подписанный этим кодом, когда я его распечатываю, всегда печатается подпись: https://s3.amazonaws.com/gxzadminlocal/anexo_28276.pdf

1 Ответ

0 голосов
/ 08 ноября 2018

Текущие версии iText 5 автоматически устанавливают флаг PRINT, если поле подписи еще не существует, и они должны его создать. Но если вы заполняете существующее поле подписи, этот флаг остается без изменений. Таким образом, вы можете захотеть добавить пустое поле подписи без этого флага PRINT на первом шаге и на втором шаге подписать, используя это поле, например, со следующим кодом:

Подготовка PDF

Вы можете подготовить PDF с пустым полем для подписи , не устанавливая флаг PRINT , например:

try (   InputStream resource = SOURCE_STREAM;
        OutputStream os = INTERMEDIATE_OUTPUT_STREAM) {
    PdfReader reader = new PdfReader(resource);
    PdfStamper stamper = new PdfStamper(reader, os);
    PdfFormField field = PdfFormField.createSignature(stamper.getWriter());
    field.setFieldName("Signature");
    field.setWidget(new Rectangle(30, 830, 170, 770), PdfAnnotation.HIGHLIGHT_NONE);
    stamper.addAnnotation(field, 1);
    stamper.close();
}

( CreateSignature тест signWidgetNoPrint проход 1)

В частности, вы не делаете

field.setFlags(PdfAnnotation.FLAGS_PRINT);

здесь!

Подписание подготовленного PDF

Создав этот промежуточный PDF, вы можете подписать его так:

try (   InputStream resource = INTERMEDIATE_INPUT_STREAM;
        OutputStream os = RESULT_STREAM) {
    PdfReader reader = new PdfReader(resource);
    PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');

    PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
    appearance.setReason("reason");
    appearance.setLocation("location");
    appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
    appearance.setVisibleSignature("Signature");

    ExternalSignature pks = new PrivateKeySignature(pk, "SHA512", "BC");
    ExternalDigest digest = new BouncyCastleDigest();
    MakeSignature.signDetached(appearance, digest, pks, chain, null, null, null, 0, CryptoStandard.CMS);
}

( CreateSignature тест signWidgetNoPrint проход 2)

при условии, что вы подготовили свой закрытый ключ в pk и цепочку сертификатов в chain; и при условии, что вы зарегистрировали Bouncy Castle в качестве поставщика услуг безопасности.

В результате PDF визуализация подписи появляется на экране, но не печатается.

...