title: Exception when add digital signature to password producted pdf using PDFBOX?
body: <p>When I am adding digital signature to the encrypted(password protected) <code>PDF</code> using <code>PDF BOX</code> am getting the following <code>exceptions</code>,</p>
  
  <pre><code>    Exception in thread "main" java.lang.NullPointerException
          at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.computeRevisionNumber(StandardSecurityHandler.java:128)
          at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.prepareDocumentForEncryption(StandardSecurityHandler.java:299)
          at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1457)
          at org.apache.pdfbox.pdmodel.PDDocument.saveIncremental(PDDocument.java:1396)
          at com.seind.pdf.digitalsignature.CreateVisibleSignature.signPDF(CreateVisibleSignature.java:187)  
          at com.seind.pdf.digitalsignature.CreateVisibleSignature.main(CreateVisibleSignature.java:305)
  </code></pre>
  
  <p>But when I am using owner password to <code>decrypt</code> the <code>PDF</code>, its not working. its correct a password which I was used to encrypt... I hope you all understand the problem and here is my sample code:</p>
  
  <pre><code>import java.io.BufferedInputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.security.KeyStore;
  import java.security.KeyStoreException;
  import java.security.NoSuchAlgorithmException;
  import java.security.PrivateKey;
  import java.security.UnrecoverableKeyException;
  import java.security.cert.CertStore;
  import java.security.cert.Certificate;
  import java.security.cert.CollectionCertStoreParameters;
  import java.security.cert.X509Certificate;
  import java.util.Arrays;
  import java.util.Calendar;
  import java.util.Enumeration;
  import java.util.List;
  
  import org.apache.pdfbox.pdfparser.PDFParser;
  import org.apache.pdfbox.pdmodel.PDDocument;
  import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial;
  import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
  import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface;
  import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions;
  import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigProperties;
  import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner;
  import org.bouncycastle.cms.CMSSignedData;
  import org.bouncycastle.cms.CMSSignedDataGenerator;
  import org.bouncycastle.cms.CMSSignedGenerator;
  import org.bouncycastle.jce.provider.BouncyCastleProvider;
  
  /**
   * This is an example for visual signing a pdf with bouncy castle.
  
   * {@see CreateSignature}
   * @author Vakhtang Koroghlishvili
   */
  
  
  public class CreateVisibleSignature implements SignatureInterface
  {
          public static final String RESOURCE ="stock1.jpg";//"Paul_Cézanne_222.jpg";//"signature-stamp.jpg";//"SJG_Signature.png";//"amber-signature.png";// "Man-Utd-v-Bayern-Munich-018.jpg";//"check_256.png";//"signature-stamp.jpg";
  
      private static BouncyCastleProvider provider = new BouncyCastleProvider();
  
      private PrivateKey privKey;
      private Certificate[] cert;
      private SignatureOptions options;
  
      public CreateVisibleSignature()
          {
  
          }
  
      /**
       * Initialize the signature creator with a keystore (pkcs12) and pin that
       * should be used for the signature.
       *
       * @param keystore is a pkcs12 keystore.
       * @param pin is the pin for the keystore / private key
       */
      public CreateVisibleSignature(KeyStore keystore, char[] pin)
      {
          try
          {
              // grabs the first alias from the keystore and get the private key. An
              // alternative method or constructor could be used for setting a specific
              // alias that should be used.
  
              Enumeration&lt;String&gt; aliases = keystore.aliases();
  
              String alias = null;
              while (aliases.hasMoreElements())
              {
                  alias = aliases.nextElement();
                  System.out.println(" alias name "+alias);
              }
  
              privKey = (PrivateKey) keystore.getKey(alias, pin);
              cert = keystore.getCertificateChain(alias);
          }
          catch (KeyStoreException e)
          {
              e.printStackTrace();
          }
          catch (UnrecoverableKeyException e)
          {
              System.err.println("Could not extract private key.");
              e.printStackTrace();
          }
          catch (NoSuchAlgorithmException e)
          {
              System.err.println("Unknown algorithm.");
              e.printStackTrace();
          }
      }
  
      /**
       * Signs the given pdf file.
       *
       * @param document is the pdf document
       * @param signatureProperties
       * @return the signed pdf document
       * @throws Exception 
       */
      public File signPDF(File document, PDVisibleSigProperties signatureProperties) throws Exception
      {
  
          PDDocument doc = openPDFDoc(document);
  
  
  
  
          byte[] buffer = new byte[8 * 1024];
  
          if (document == null || !document.exists())
          {
              new RuntimeException("Document for signing does not exist");
          }
  
          // creating output document and prepare the IO streams.
          String name = document.getName();
  
          String substring = name.substring(0, name.lastIndexOf("."));
  
          File outputDocument = new File(document.getParent(), substring + "_signed.pdf");
  
          FileInputStream fis = new FileInputStream(document);
  
          FileOutputStream fos = new FileOutputStream(outputDocument);
  
          int c;
          while ((c = fis.read(buffer)) != -1)
          {
              fos.write(buffer, 0, c);
          }
          fis.close();
  
          fis = new FileInputStream(outputDocument);
  
          // load document
        //  PDDocument doc = PDDocument.load(document);
  
          // create signature dictionary
          PDSignature signature = new PDSignature();
          signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); // default filter
          // subfilter for basic and PAdES Part 2 signatures
          signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
          signature.setName(signatureProperties.getSignerName());
          signature.setLocation("chennai");
          //signature.setReason("reason for signature");
  
          // the signing date, needed for valid signature
          signature.setSignDate(Calendar.getInstance());
  
          // register signature dictionary and sign interface
  
         options = new SignatureOptions();
  
         options.setVisualSignature(signatureProperties);
  
         // options.setPage(signatureProperties.getPage());
         //options.setPreferedSignatureSize(signatureProperties.getPreferredSize());
  
         doc.addSignature(signature, this, options);
  
         doc.saveIncremental(fis, fos);
  
         return outputDocument;
      }
  
          PDDocument openPDFDoc(File pdfFile) throws Exception 
      {
  
          File originalPDF = pdfFile;
  
          PDFParser parser = new PDFParser(new BufferedInputStream(new FileInputStream(originalPDF)));
  
          parser.parse();
  
          PDDocument originialPdfDoc = parser.getPDDocument();
  
          boolean isOriginalDocEncrypted = originialPdfDoc.isEncrypted();
  
          if (isOriginalDocEncrypted)
          {
  
              originialPdfDoc.openProtection(new StandardDecryptionMaterial("123456"));
  
          }
  
  
          return originialPdfDoc;
      } 
  
  
      /**
       * SignatureInterface implementation.
       *
       * This method will be called from inside of the pdfbox and create the pkcs7 signature.
       * The given InputStream contains the bytes that are given by the byte range.
       *
       * This method is for internal use only. &lt;-- TODO this method should be private
       *
       * Use your favorite cryptographic library to implement pkcs7 signature creation.
       */
      @SuppressWarnings("deprecation")
      @Override
      public byte[] sign(InputStream content) throws IOException
      {
          CMSProcessableInputStream input = new CMSProcessableInputStream(content);
          CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
          // CertificateChain
          List&lt;Certificate&gt; certList = Arrays.asList(cert);
  
          CertStore certStore = null;
          try
          {
              certStore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), provider);
              gen.addSigner(privKey, (X509Certificate) certList.get(0), CMSSignedGenerator.DIGEST_SHA256);
              gen.addCertificatesAndCRLs(certStore);
              CMSSignedData signedData = gen.generate(input, false, provider);
              return signedData.getEncoded();
          }
          catch (Exception e)
          {
              // should be handled
              System.err.println("Error while creating pkcs7 signature.");
              e.printStackTrace();
          }
          throw new RuntimeException("Problem while preparing signature");
      }
  
      public static void main(String[] args) throws Exception
      {
          //String pdfPath="E:\\outputs1\\iText in Action.pdf";
  
            String pdfPath="E:\\outputs1\\CNB_20131029_AAPL034_0490301_NSEFO_ECN_iPass.pdf";
  
          //  new PdfOptimize().reducePdfSize(pdfPath);
  
            File ksFile = new File("E:/sol.p12");
  
            KeyStore keystore = KeyStore.getInstance("PKCS12", provider);
  
            char[] pin = "xxxxxxx".toCharArray();
  
            keystore.load(new FileInputStream(ksFile), pin);
  
  
  
            //String pdfPath="E:\\temp\\pdf\\security\\password\\hello_iText.pdf";
  
              File document = new File(pdfPath);
  
              CreateVisibleSignature signing = new CreateVisibleSignature(keystore, pin.clone());
  
              FileInputStream image = new FileInputStream(RESOURCE);
  
              PDVisibleSignDesigner visibleSig = new PDVisibleSignDesigner(pdfPath, image, 1);
  
              visibleSig.xAxis(660).yAxis(480).zoom(-50).signatureFieldName("signature");
  
              visibleSig.height(37);
  
              visibleSig.width(70);
  
              //visibleSig.imageSizeInPercents(50);
  
              PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
  
              signatureProperties.signerName("XXXXXXX").signerLocation("chennai").signatureReason("Security").preferredSize(0)
                      .page(1).visualSignEnabled(true).setPdVisibleSignature(visibleSig).buildSignature();
  
  
              signatureProperties.setPdVisibleSignature(visibleSig);
  
              signing.signPDF(document, signatureProperties);
  
      }
  
  
  }
  </code></pre>
  
  <p>And most of the methods are <code>deprecated</code> which are used to verify the owner password ,user password and etc.</p>