pdfbox-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Wall <david.w...@yozons.com>
Subject PDF digital signature is no longer valid using BC 1.51
Date Fri, 24 Oct 2014 22:06:20 GMT
I'm now getting an invalid digital signature that I created on PDFs we 
generate (via wkhtmltopdf and PDFBox 1.8.7).  It says "At least one 
signature is invalid" but I previously could create them with valid 
signatures.  This occurred when going from BouncyCastle 1.50 to 1.51, 
and if I go back to 1.50, it works fine.

The invalid signature complains that the "Document has been altered or 
corrupted since it was signed".

Here's a link to an existing PDF that has an invalid signature:
http://open.esignforms.com/pdfboxlist/MyDocumentsGOOD.pdf (using BC 1.50)
http://open.esignforms.com/pdfboxlist/MyDocumentsBAD.pdf (using BC 1.51)

I am using Java 7.

Here are the relevant Java code:

     boolean signPdf(File pdfFile, File signedPdfFile)
     {
         FileInputStream fis = null;
         FileOutputStream fos = null;
         PDDocument doc = null;

         try
         {
             fis = new FileInputStream(pdfFile);
             fos = new FileOutputStream(signedPdfFile);

             int readCount;
             byte[] buffer = new byte[8 * 1024];
             while ((readCount = fis.read(buffer)) != -1)
             {
               fos.write(buffer, 0, readCount);
             }
             fis.close();
             fis = new FileInputStream(signedPdfFile);

             doc = PDDocument.load(pdfFile);
             PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
             signature.setName("Open eSignForms Export PDF Integrity 
Lock");
signature.setLocation(Application.getInstance().getExternalContextPath());
             signature.setReason("Used to ensure that an exported PDF 
has not been tampered with since its generation by Open eSignForms 
deployment id: " +
  Application.getInstance().getDeployId());
             signature.setSignDate(Calendar.getInstance());
             doc.addSignature(signature, this);
             doc.saveIncremental(fis, fos);
             return true;
         }
         catch( Exception e )
         {
             _logger.error("signPdf() - Failed to sign the PDF",e);
             return false;
         }
         finally
         {
             if ( fis != null ) try { fis.close(); } catch( Exception e 
) {}
             if ( fos != null ) try { fos.close(); } catch( Exception e 
) {}
             if ( doc != null ) try { doc.close(); } catch( Exception e 
) {}
         }
     }

     @Override
     public byte[] sign(InputStream is) throws SignatureException, 
IOException
     {
         Application app = Application.getInstance();
         try
         {
             String provider = app.getPublicKeyGenerator().getProvider();
             SignatureKey signatureKey = app.getSignatureKey();
             X509Certificate cert = signatureKey.getX509Certificate();
             Store certStore = new JcaCertStore(Arrays.asList(cert));

             CMSTypedDataInputStream input = new 
CMSTypedDataInputStream(is);
             CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
             ContentSigner sha512Signer = new 
JcaContentSignerBuilder(PublicKeyGenerator.SIGNATURE_ALGORITHM).setProvider(provider).build(signatureKey.getPrivateKey());

             gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                     new 
JcaDigestCalculatorProviderBuilder().setProvider(provider).build()).build(sha512Signer, 
cert));
             gen.addCertificates(certStore);
             CMSSignedData signedData = gen.generate(input, false);

             return signedData.getEncoded();
         }
         catch (Exception e)
         {
             _logger.error("sign() - Problem while preparing PDF 
signature",e);
             return null;
         }
     }

     class CMSTypedDataInputStream implements CMSTypedData
     {

         InputStream in;

         public CMSTypedDataInputStream(InputStream is)
         {
             in = is;
         }

         @Override
         public ASN1ObjectIdentifier getContentType()
         {
             return PKCSObjectIdentifiers.data;
         }

         @Override
         public Object getContent()
         {
             return null;
         }

          @Override
          public void write(OutputStream out) throws IOException, 
CMSException
          {
              byte[] buffer = new byte[8 * 1024];
              int read;
              while( (read = in.read(buffer)) != -1 )
              {
                  out.write(buffer, 0, read);
             }
             in.close();
          }
     }


Mime
View raw message