javapdfitextdigital-signaturepdfstamper

Digital Signature For PDF Documents


Is it possible to generate digital signature for already signed PDF document ? I am using following code to generate digital signature for PDF documents.

public void sign(String src, String dest, Certificate[] chain, PrivateKey 
   pk, String digestAlgorithm,String provider, CryptoStandard subfilter, 
   String reason, String location) {


        PdfReader reader;
        FileOutputStream os;
        PdfStamper stamper;

        try {
            reader = new PdfReader(src);
            File destFile = new File(dest);
            String destFilePath = destFile.getAbsolutePath();
            System.out.println("destFilePath=====" + destFilePath);
            os = new FileOutputStream(dest);
            System.out.println("File output " + os);
            stamper = PdfStamper.createSignature(reader, os, '\0');
            System.out.println("stamper " + stamper.getSignatureAppearance());
            // Creating the appearance
            PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
            System.out.println("Appearance " + appearance);
            // appearance.setImage(Image.getInstance("F:/Unibrain/EbidUploadedFolder/" +
            // "/resources/55.png"));
            appearance.setImage(Image.getInstance("F:\\55.png"));
            // appearance.setReason(reason);
            // appearance.setLocation(location);
            appearance.setVisibleSignature(new Rectangle(800, 732, 512, 780), 1, "sig");
            appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION);
            appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);
            Rectangle cropbox = reader.getCropBox(1);
            float width = 250;
            float height = 50;
            Rectangle rectangle = new Rectangle(cropbox.getRight(width), cropbox.getBottom(), cropbox.getRight(),
                    cropbox.getBottom(height));
            cropbox.setBorderWidth(5);
            appearance.setVisibleSignature(rectangle, 1, "sig");
            // Creating the signature
            ExternalDigest digest = new BouncyCastleDigest();
            System.out.println("digest " + digest);
            ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, provider);
            System.out.println("Signature " + signature);
            MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Solution

  • Is it possible to generate digital signature for already signed PDF document ?

    In general yes but the additional signature must be added in an incremental update to not invalidate the pre-existing signature. For some backgrounds see this answer.

    In case of your code this means that you have to replace the line

    stamper = PdfStamper.createSignature(reader, os, '\0');
    

    by

    stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
    

    The true indicates that the signature shall be applied in append mode which is iText lingo for adding changes in an incremental update.

    Furthermore you have to make sure that the new signature is created in a different form field. Your code adds the signature into the had-coded field "sig":

    appearance.setVisibleSignature(new Rectangle(800, 732, 512, 780), 1, "sig");
    

    If you know that the name of the field of the pre-existing signature differs, this is ok. Otherwise you might want to replace "sig" by null which makes iText create a unique field name for the new signature.


    Above I said "in general yes" - there is an exception, if the original signature is a certification signature with "no changes allowed", applying an additional signature will break the original signature as applying it is a change.