Search code examples
digital-signatureitext7

Signature field remain unsigned after the signing


I was performing signing using the iText7 library. I tried signing one of the signature fields available on the document but after the signing, it still shows that field is unsigned. The following is the code snippet that I'm using for signing.

String fieldName = "signature1";
PdfAcroForm pdfAcroForm = PdfAcroForm.getAcroForm(pdfDocument, false);
PdfArray pdfArray = pdfAcroForm.getField(fieldName).getWidgets().get(0).getRectangle();
Rectangle rect = pdfArray.toRectangle();
PdfSignatureAppearance appearance = pdfSigner.getSignatureAppearance().setReason("Test")
    .setLocation("Test").setReuseAppearance(false);
appearance.setPageRect(rect).setPageNumber(1);
IExternalSignature pks =
     new PrivateKeySignature(pk, DigestAlgorithms.SHA256, provider.getName());
pdfSigner.signDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, CryptoStandard.CMS);

original pdf & signed pdf

Updated

For the following pdf, I'm not getting the signature visibility on the document despite signing the field as mentioned in the response; however, working for the above earlier shared pdf.

pdfSigner.setFieldName(fieldName);

original pdf & signed pdf


Solution

  • The Original Issue

    You forgot to tell the PdfSigner to sign one of the existing form fields, so it creates a new field and signs that.

    To tell iText to use a specific field, use PdfSigner.setFieldName:

    pdfSigner.setFieldName(fieldName);
    

    According to its JavaDocs this method

    Sets the name indicating the field to be signed. The field can already be presented in the document but shall not be signed. If the field is not presented in the document, it will be created.

    ("presented" should have been "present" I guess...)

    Once you do so, there is no need for

    appearance.setPageRect(rect).setPageNumber(1);
    

    anymore as the rectangle and page number of the existing form field are used.

    The Issue With FORM FDA 1571

    In an update you shared a file for which the signature appearance did not show in spite of the correction mentioned above, a FDA 1571 form.

    The reason for this is simple: The signature fields in that document are invisible, before and after signing!

    before signing after signing
    before signing after signing

    Thus, it's completely correct that you don't see the signature appearance.

    If you want a visible signature appearance, you have to make sure that the signature field is visible.

    There are a number of situations in which a signature appearance is invisible, in particular:

    • The signature widget is not referenced from any page.
    • The Rect entry of the signature widget is off-page (outside the crop box of the page).
    • The Rect entry of the signature widget has a width or height of 0.
    • The signature widget belongs to an optional content group (aka layer) which is switched off.
    • One of the signature widget flags Invisible, Hidden, or NoView is set.

    In case of your form FDA 1571 the Hidden flag is set.

    You can unset that flag like this:

    PdfAcroForm.getAcroForm(pdfSigner.getDocument(), false)
        .getField(fieldName)
        .setVisibility(PdfFormField.VISIBLE);
    

    (From SignWithAdaptions test testFda1571)

    If you wonder why after manually signing the document the signature is visible: The sign button on the form executes a bit of JavaScript which among other things also clears that Hidden flag.