PDF External Signature

Previous Topic Next Topic
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view

PDF External Signature

Hi all,

I want to external signature for pdf. My codes:

import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfDate;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignature;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.security.DigestAlgorithms;
import com.itextpdf.text.pdf.security.ExternalDigest;
import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.HashMap;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

 * @author murat.demir
public class PdfSignOperation {

    private byte[] content = null;
    private X509Certificate x509Certificate;
    private PdfReader reader = null;
    private ByteArrayOutputStream baos = null;
    private PdfStamper stamper = null;
    private PdfSignatureAppearance sap = null;
    private PdfSignature dic = null;
    private HashMap<PdfName, Integer> exc = null;
    private ExternalDigest externalDigest = null;
    private PdfPKCS7 sgn = null;
    private InputStream data = null;
    private byte hash[] = null;
    private Calendar cal = null;
    private byte[] sh = null;
    private byte[] encodedSig = null;
    private byte[] paddedSig = null;
    private PdfDictionary dic2 = null;

    static {
        Security.addProvider(new BouncyCastleProvider());

    public PdfSignOperation(byte[] content, X509Certificate cert) {
        this.content = content;
        this.x509Certificate = cert;

    public byte[] getHash() throws Exception {
        reader = new PdfReader(new ByteArrayInputStream(content));

        baos = new ByteArrayOutputStream();
        stamper = PdfStamper.createSignature(reader, baos, '\0');
        sap = stamper.getSignatureAppearance();

        sap.setLocation("On a server!");
        sap.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");

        dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
        dic.setDate(new PdfDate(sap.getSignDate()));

        exc = new HashMap<PdfName, Integer>();
        exc.put(PdfName.CONTENTS, new Integer(8192 * 2 + 2));

        externalDigest = new ExternalDigest() {
            public MessageDigest getMessageDigest(String hashAlgorithm)
                    throws GeneralSecurityException {
                return DigestAlgorithms.getMessageDigest(hashAlgorithm, null);

        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = x509Certificate;

        sgn = new PdfPKCS7(null, chain, "SHA256", null, externalDigest, false);
        data = sap.getRangeStream();

        hash = DigestAlgorithms.digest(data, externalDigest.getMessageDigest("SHA256"));
        return hash;

    public String complateToSignature(byte[] signedHash) throws Exception {
        cal = Calendar.getInstance();
        sgn.setExternalDigest(signedHash, hash, "RSA");
        encodedSig = sgn.getEncodedPKCS7(hash, cal, null, null, null, CryptoStandard.CMS);
        paddedSig = new byte[8192];

        System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length);
        dic2 = new PdfDictionary();

        dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));

        return Base64.encodeBytes(baos.toByteArray());


  public static void main(String[] args) throws Exception {
        File pdf = new File("E:/sample.pdf");
        FileInputStream is = new FileInputStream(pdf);
        byte[] content = new byte[is.available()];
        X509Certificate certificate = null;
        for (CertInfo certInfo : TokenService.getCertificates().values()) {
            if (certInfo.cert != null) {
                certificate = certInfo.cert;

        PdfSignOperation operation = new PdfSignOperation(content, certificate);

        byte[] hash = operation.getHash();

        String alias = "alias";
        String pin = "1242";
        TokenService.setAliasPin(alias, pin);
        byte[] signedData = TokenService.sign(hash, alias);



modified or corrupted after the document is signed
Reply | Threaded
Open this post in threaded view

Re: PDF External Signature

mdemir wrote
I want to external signature for pdf. My codes:



modified or corrupted after the document is signed
See the answer to the parallel post on stackoverflow:


Regards,   Michael