Information Security 16 min read

Electronic Signature Implementation Using Java and PDF

This tutorial explains China’s electronic‑seal regulations, shows how to generate a CA‑based X.509 certificate and a custom seal image with BouncyCastle, and demonstrates signing a PDF in Java using iText 5 to embed a visible seal and a verifiable digital signature.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
Electronic Signature Implementation Using Java and PDF

This article explains the legal and technical background of electronic signatures in China and demonstrates how to create a CA‑based digital certificate, generate a seal image, and apply a visible electronic signature to a PDF file using Java.

What is an electronic seal? An electronic seal combines a digital signature (generated with a CA certificate) and a visual seal image. The signature guarantees integrity and non‑repudiation, while the image provides the familiar visual cue of a stamped document.

CA digital certificate acts like an electronic ID. It is issued by a certified authority (CA) and contains a public‑key certificate and a private key held by the signer. The certificate is stored in the signed PDF and can be verified by any recipient.

Signature process – The signer hashes the PDF (including the seal image and its position) using SHA‑256, encrypts the hash with the private key, and embeds the resulting signature and the public‑key certificate into the PDF’s signature field. Verification involves extracting the public key, decrypting the signature, and comparing the hash.

Technical selection – Two main Java libraries are compared:

Apache PDFBox – weaker feature set, free (Apache 2.0).

iText (5/7) – richer features, AGPL license (commercial use requires a paid license).

The tutorial chooses iText5 for its comprehensive support of custom seal drawing and signing.

1. Generate a digital certificate (Maven dependencies)

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.70</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-ext-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

Utility class PkcsUtils creates a PKCS#12 keystore, a X.509 certificate, and extracts the public/private keys. The main method shows how to set the issuer/subject DN and write keystore.p12 and keystore.cer files.

2. Generate a seal image

public class SealSample {
    public static void main(String[] args) throws Exception {
        Seal seal = new Seal();
        seal.setSize(200);
        SealCircle sealCircle = new SealCircle();
        sealCircle.setLine(4);
        sealCircle.setWidth(95);
        sealCircle.setHeight(95);
        seal.setBorderCircle(sealCircle);
        SealFont mainFont = new SealFont();
        mainFont.setText("江南一点雨股份有限公司");
        mainFont.setSize(22);
        mainFont.setFamily("隶书");
        mainFont.setSpace(22.0);
        mainFont.setMargin(4);
        seal.setMainFont(mainFont);
        SealFont centerFont = new SealFont();
        centerFont.setText("★");
        centerFont.setSize(60);
        seal.setCenterFont(centerFont);
        SealFont titleFont = new SealFont();
        titleFont.setText("财务专用章");
        titleFont.setSize(16);
        titleFont.setSpace(8.0);
        titleFont.setMargin(54);
        seal.setTitleFont(titleFont);
        seal.draw("公章1.png");
    }
}

The generated PNG (e.g., 公章1.png ) can be used as the visual seal in the PDF.

3. Sign the PDF with iText5

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.4</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>html2pdf</artifactId>
    <version>5.0.5</version>
</dependency>

Core signing method:

public static byte[] sign(String password, String keyStorePath, String pdfPath, String imagePath, float x, float y) {
    KeyStore ks = KeyStore.getInstance("PKCS12", new BouncyCastleProvider());
    ks.load(new FileInputStream(keyStorePath), password.toCharArray());
    String alias = ks.aliases().nextElement();
    PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());
    Certificate[] chain = ks.getCertificateChain(alias);
    PdfReader reader = new PdfReader(pdfPath);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    PdfStamper stamper = PdfStamper.createSignature(reader, out, '\0');
    PdfSignatureAppearance sap = stamper.getSignatureAppearance();
    sap.setReason("数字签名,不可改变");
    Image img = Image.getInstance(imagePath);
    sap.setSignatureGraphic(img);
    sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
    sap.setVisibleSignature(new Rectangle(x, y, x+185, y+68), 1, UUID.randomUUID().toString().replaceAll("-", ""));
    ExternalDigest digest = new BouncyCastleDigest();
    ExternalSignature signature = new PrivateKeySignature(key, DigestAlgorithms.SHA512, "BC");
    MakeSignature.signDetached(sap, digest, signature, chain, null, null, null, 0, MakeSignature.CryptoStandard.CADES);
    return out.toByteArray();
}

The main method calls sign with the generated keystore.p12 , the target PDF, and the seal image, producing a signed PDF that displays the visual seal and contains a verifiable digital signature.

In summary, the guide covers the legal definition of electronic seals, the creation of a CA‑based certificate with BouncyCastle, seal image generation, and the complete PDF signing workflow using iText5. This provides a practical, end‑to‑end solution for secure electronic document signing in Java.

JavaBouncyCastleDigital Certificateelectronic signatureiTextPDF
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.