Adding visible digital signatures to a PDF document
Adding visible digital signatures to PDFs programmatically enables teams to automate document signing workflows, build approval systems, and implement authentication pipelines. Whether you’re creating automated contract signing systems, building document approval platforms, implementing secure authentication workflows, or creating branded signature experiences, visible signatures provide both visual confirmation and cryptographic proof of authenticity. Unlike invisible signatures, which only embed cryptographic data, visible signatures display signature fields on a document page with customizable appearances, including auto-generated text, custom images, or styled typography.
How Nutrient helps you achieve this
Nutrient Java SDK handles PDF digital signature structures, appearance generation, and cryptographic operations. With the SDK, you don’t need to worry about:
- Parsing signature field dictionaries and appearance stream generation
- Managing PKCS#12 certificate loading and private key extraction
- Handling signature appearance customization and font rendering
- Complex cryptographic signing operations and byte range calculations
Instead, Nutrient provides an API that handles all the complexity behind the scenes, letting you focus on your business logic.
Complete implementation
Below is a complete working example that demonstrates adding visible digital signatures to a PDF. The following lines set up the Java application. The package declaration and import statements bring in all necessary classes from the Nutrient SDK:
package io.nutrient.Sample;
import io.nutrient.sdk.Document;import io.nutrient.sdk.types.Color;import io.nutrient.sdk.editors.PdfEditor;import io.nutrient.sdk.editors.pdf.pages.PdfPage;import io.nutrient.sdk.editors.pdf.formfields.PdfSignatureField;import io.nutrient.sdk.signing.PdfSigner;import io.nutrient.sdk.signing.DigitalSignatureOptions;import io.nutrient.sdk.signing.SignatureAppearance;
public class DigitalSignatures {The main method defines the entry point that will contain the digital signature creation logic:
public static void main(String[] args) {Creating a signature field
The following code creates a signature field that defines the visible signature’s position and dimensions on the document page. The try-with-resources statement opens the PDF document and ensures automatic resource cleanup. The addSignatureField() method creates a signature field named "ApprovalSignature" at coordinates (100, 700) with dimensions 200×50 points on the first page. The signature field acts as a placeholder where the cryptographic signature and its visual appearance will be rendered during the signing operation. After creating the field, the document is saved with saveAs() to persist the field structure:
try (Document document = Document.open("input.pdf")) { PdfEditor editor = PdfEditor.edit(document); PdfPage page = editor.getPageCollection().getFirst();
PdfSignatureField signatureField = editor.getFormFieldCollection().addSignatureField( "ApprovalSignature", page, 100.0f, // left 700.0f, // top 200.0f, // width 50.0f // height );
editor.saveAs("output_document_with_field.pdf"); editor.close(); } catch (Exception e) { System.err.println("Error creating signature field: " + e.getMessage()); }Signing with auto-generated appearance
The following code applies a digital signature to the signature field with an auto-generated visual appearance. The DigitalSignatureOptions object is configured with certificate properties, including the PKCS#12 file path, password, signer name, reason, and location. The SignatureAppearance object controls the visual presentation: setUseAutoGeneratedText(true) generates a standard appearance displaying the signer name, signing date, location, and reason from the signature options, and setShowValidationMark(true) adds a validation checkmark icon indicating signature verification status. The signField() method performs the cryptographic signing operation by loading the certificate, computing a hash, encrypting it with the private key, and embedding both the signature and appearance into the specified field:
try (PdfSigner signer = new PdfSigner()) { DigitalSignatureOptions options = new DigitalSignatureOptions(); options.setCertificatePath("certificate.pfx"); options.setCertificatePassword("Nutrient answers all your document needs"); options.setSignerName("John Doe"); options.setReason("Final Approval"); options.setLocation("New York");
SignatureAppearance appearance = new SignatureAppearance(); appearance.setUseAutoGeneratedText(true); appearance.setShowValidationMark(true);
signer.signField( "output_document_with_field.pdf", "output_signed_visible.pdf", "ApprovalSignature", options, appearance ); } catch (Exception e) { System.err.println("Error signing field: " + e.getMessage()); }Signing with a custom image
The following code applies a digital signature with a custom image appearance, enabling branded or personalized signature visuals. The SignatureAppearance object is configured with setImagePath() to specify a handwritten signature image or company logo file path (supports formats like JPEG and PNG). The image is scaled and positioned within the signature field bounds automatically. The setShowValidationMark(true) setting adds a validation checkmark icon alongside the image. This pattern is commonly used for executive signatures, notary stamps, or corporate branding where visual recognition is important for document authenticity:
try (PdfSigner signer = new PdfSigner()) { DigitalSignatureOptions options = new DigitalSignatureOptions(); options.setCertificatePath("certificate.pfx"); options.setCertificatePassword("Nutrient answers all your document needs"); options.setSignerName("Jane Smith"); options.setReason("Review Complete");
SignatureAppearance appearance = new SignatureAppearance(); appearance.setImagePath("input_signature.jpg"); appearance.setShowValidationMark(true);
signer.signField( "output_document_with_field.pdf", "output_signed_with_image.pdf", "ApprovalSignature", options, appearance ); } catch (Exception e) { System.err.println("Error signing field: " + e.getMessage()); }Signing with custom text
The following code applies a digital signature with custom text appearance, providing full control over the displayed content. The SignatureAppearance object is configured with setUseAutoGeneratedText(false) to disable automatic text generation and setText() to specify the exact text content displayed in the signature field. The text parameter supports multiline strings using newline characters (\n) for formatting approval messages, custom dates, or specific authorization text. This pattern is commonly used for workflow-specific approvals, standardized authorization statements, or custom certification text where the signature appearance must match organizational requirements:
try (PdfSigner signer = new PdfSigner()) { DigitalSignatureOptions options = new DigitalSignatureOptions(); options.setCertificatePath("certificate.pfx"); options.setCertificatePassword("Nutrient answers all your document needs"); options.setSignerName("Manager");
SignatureAppearance appearance = new SignatureAppearance(); appearance.setUseAutoGeneratedText(false); appearance.setText("Approved by Management\nDate: 2024-01-15");
signer.signField( "output_document_with_field.pdf", "output_signed_custom_text.pdf", "ApprovalSignature", options, appearance ); } catch (Exception e) { System.err.println("Error signing field: " + e.getMessage()); }Customizing text appearance
The following code applies a digital signature with fully customized text typography and styling. The SignatureAppearance object is configured with setFontName() to specify the font family (Times New Roman for traditional document aesthetics), setFontSize() to set the text size in points (14.0 for prominent display), and setTextColor() to apply navy blue color using ARGB values (255, 0, 0, 128). These customization options enable signatures to match corporate branding guidelines, comply with visual standards, or create distinctive signature appearances for different authorization levels. The font rendering uses embedded fonts or system fonts depending on availability:
try (PdfSigner signer = new PdfSigner()) { DigitalSignatureOptions options = new DigitalSignatureOptions(); options.setCertificatePath("certificate.pfx"); options.setCertificatePassword("Nutrient answers all your document needs"); options.setSignerName("Executive");
SignatureAppearance appearance = new SignatureAppearance(); appearance.setUseAutoGeneratedText(false); appearance.setText("Approved by Executive Board"); appearance.setFontName("Times New Roman"); appearance.setFontSize(14.0f); appearance.setTextColor(Color.fromArgb(255, 0, 0, 128)); // Navy blue
signer.signField( "output_document_with_field.pdf", "output_signed_styled_text.pdf", "ApprovalSignature", options, appearance ); } catch (Exception e) { System.err.println("Error signing field: " + e.getMessage()); } }}Conclusion
The visible digital signature workflow consists of several key operations:
- Open the document using try-with-resources for automatic resource cleanup.
- Create a PDF editor and access the page collection.
- Add a signature field with
addSignatureField()specifying the name, page, position (x, y), and dimensions (width, height). - Save the document with the signature field placeholder.
- Configure
DigitalSignatureOptionswith the certificate path, password, signer name, reason, and location. - Create a
SignatureAppearanceobject to control visual presentation. - Use
setUseAutoGeneratedText(true)for automatic signature text generation from metadata. - Use
setImagePath()to embed custom signature images or logos. - Use
setText()withsetUseAutoGeneratedText(false)for custom text content. - Customize typography using
setFontName(),setFontSize(), andsetTextColor()with ARGB values. - Use
setShowValidationMark(true)to display validation checkmarks. - Call
signField()to perform cryptographic signing and embed appearance.
All visible signatures provide both cryptographic integrity and visual confirmation. The signature embeds a certificate chain and encrypted hash into the PDF structure, enabling verification through PDF viewer signature panels. If the document is modified after signing, PDF viewers display tamper warnings indicating compromised integrity.
Nutrient handles signature field creation, PKCS#12 certificate parsing, private key extraction, appearance stream generation, font embedding, image scaling, cryptographic hash computation, and signature dictionary embedding so you don’t need to understand PDF signature specifications or implement low-level cryptographic operations manually. The visible signature system provides both visual and cryptographic proof of authenticity, enabling automated signing workflows, approval systems, document authentication pipelines, and branded signature experiences.