Skip to content
Add Multiple Signature Field

Add Multiple Signature Field

Two people signing the same document means two signatures, each covering more of the file than the last. Every signature gets its own incremental revision, so the second signer’s bytes are appended after the first signature’s byte range and the first signature stays verifiable. What you cannot do is add both in one appender pass.

There is a related but different case: one signature drawn in several places. If the same person’s signature should appear on every page, reuse one PdfSignature across several fields, as in Create Appearance Field for Digital Signature. Use the pattern below when the signatures are genuinely separate, made with different keys or at different times.

Signing twice

// First signature.
buf, err := addSignature(pdfReader, 0)
if err != nil {
    return err
}

// Reopen the signed bytes and sign again.
pdfReader, err = model.NewPdfReader(bytes.NewReader(buf))
if err != nil {
    return err
}

buf, err = addSignature(pdfReader, 1)
if err != nil {
    return err
}

return os.WriteFile(outputPath, buf, 0666)

Each addSignature call builds its own appender, its own handler and its own signature, writes to a buffer, and hands the bytes on. The reopen in between is what makes the second signature a new revision rather than an edit to the first.

Field names

Signature field names have to be unique across the document. Sign fills in a default of Signature <pageNum> when field.T is empty, which produces a duplicate the moment two signatures land on the same page, so name them yourself:

sigField.T = core.MakeString(fmt.Sprintf("New Page Signature %d", signNumber))

The example also offsets each appearance rectangle by the signature number, so the two boxes sit side by side instead of on top of each other:

opts.Rect = []float64{float64(50 + signNumber*100), 250, float64(150 + signNumber*100), 300}

Limitations

PdfAppender.Write can only be called once. A second call returns appender write can only be invoked once, which is the other reason each signature needs a fresh appender.

Every extra signature grows the file by a full revision, including a new AcroForm and a new copy of the pages you touched. Signing a large document ten times is ten appended revisions, not ten small dictionaries.

If the first signature was certified with a DocMDP restriction, whether a second signature is permitted depends on the level. mdp.NoChanges invalidates the first signature on any subsequent change; mdp.FillForms and mdp.FillFormsAndAnnots both allow signing. See Sign and Configure DocMDP Restriction.

The appender skips one of its own optimizations on documents that already carry a signature: it will not supersede a stale linearization dictionary, since replacing an object counts as a modification a certified document may forbid. Nothing to do about it, but it explains why the output of a second signing pass differs slightly in structure from the first.

Run the example

addSignature is called twice, with signNumber 0 and 1, each time on a reader over the previous output. Both signatures use freshly generated self-signed keys.

git clone https://github.com/unidoc/unipdf-examples.git
cd unipdf-examples/signatures
go run pdf_sign_twice_visible_annotation.go <IN.pdf> <OUT.pdf>

If this is your first time using UniPDF, follow the getting started guide to create an API key and set up your development environment.

View the full source

Sample output

Two signature appearances added in separate revisions

Last updated on