title: get hash from pdf with iText 2.1.7 or Digital Signature Service
body: <p>I'm migrating a project from iText 5 to iText 2/or DSS (<a href="https://ec.europa.eu/cefdigital/wiki/display/CEFDIGITAL/eSignature" rel="nofollow noreferrer">https://ec.europa.eu/cefdigital/wiki/display/CEFDIGITAL/eSignature</a>.)</p>
  
  <p>Due to the difference between iText versions (DSS use iText 2.17) i can't get  a proper signed hash. </p>
  
  <p>Here the code migrated from itex 5 : </p>
  
  <pre class="lang-java prettyprint-override"><code>            // We get the self-signed certificate from the client
              CertificateFactory factory = CertificateFactory.getInstance("X.509");
              Certificate[] chain = new Certificate[1];
              chain[0] = factory.generateCertificate(new ByteArrayInputStream(decoded));
  
              // we create a reader and a stamper
              PdfReader reader = new PdfReader(hash.getInputFile());
              try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
  
                  PdfStamper stamper = PdfStamper.createSignature(reader,
                                                                  byteArrayOutputStream,
                                                                  '\0',
                                                                  null,
                                                                  true);
  
                  // HERE WE HAD SOME DIFFERENCE                 
                  PdfSignatureAppearance sap = stamper.getSignatureAppearance();
  
                  sap.setVisibleSignature(new Rectangle(36, 748, 36, 748), 1, signField); //invisible
  
                  // iText 5: 
                  //sap.setCertificate(chain[0]);
  
                  // iText 2.1.7: 
                  sap.setCrypto(null,chain,null,PdfSignatureAppearance.SELF_SIGNED);
  
  
                  PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
                  dic.setReason(sap.getReason());
                  dic.setLocation(sap.getLocation());
                  dic.setContact(sap.getContact());
  
                  dic.setDate(new PdfDate(sap.getSignDate()));
                  sap.setCryptoDictionary(dic);
                  HashMap&lt;PdfName,Integer&gt; exc = new HashMap&lt;&gt;();
                  exc.put(PdfName.CONTENTS, 8192 * 2 + 2);
                  sap.preClose(exc);
  
  
  
                  // iText 5: 
                  /* 
                  ExternalDigest externalDigest = hashAlgorithm -&gt;
                          DigestAlgorithms.getMessageDigest(hashAlgorithm, null);
  
                  ExternalDigest externalDigest = new ExternalDigest() {
                      public MessageDigest getMessageDigest(String hashAlgorithm)
                              throws GeneralSecurityException {
                          return DigestAlgorithms.getMessageDigest(hashAlgorithm, null);
                      }
                  };
  
                  PdfPKCS7 sgn = new PdfPKCS7(null,
                          chain,
                          "SHA256",
                          null,
                          externalDigest,
                          false);
                  */
                  // iText 2.1.7: 
                  PdfPKCS7 sgn = new PdfPKCS7(null,chain,null, "SHA256",null,false);
  
                  // WARNING SAP.getRange different response content!!!
                  InputStream data = sap.getRangeStream();
  
  
                  // iText 5:
                  //byte[] hashArray = DigestAlgorithms.digest(data, externalDigest.getMessageDigest("SHA256"));
  
                  //iText 2
                  MessageDigest md = MessageDigest.getInstance("SHA-256");
                  byte[] hashArray = md.digest(IOUtils.toByteArray(data));
  
  
                  byte[] ocsp = null;
  
                  // iText 5:
                  //byte[] sh = sgn.getAuthenticatedAttributeBytes(hashArray,
                  //      null,
                  //      null,
                  //      MakeSignature.CryptoStandard.CMS);
  
                  // iText 2:
                  Calendar cal = Calendar.getInstance();
                  byte[] sh = sgn.getAuthenticatedAttributeBytes(hashArray,cal,null);
  
                  InputStream shInputStream = new ByteArrayInputStream(sh);
  
                  // iText 5:
                  //byte[] signedAttributesHash = DigestAlgorithms.digest(shInputStream,externalDigest.getMessageDigest("SHA256"));
  
                  // iText 2:
                  byte[] signedAttributesHash = md.digest(IOUtils.toByteArray(shInputStream));                
  
  
                  hash.setOcsp(ocsp);                
                  hash.setSgn(sgn);
                  hash.setFilehash(hashArray);
                  hash.setSap(sap);
                  hash.setBaos(byteArrayOutputStream);
  
                  hash.setSignedAttributesHashB64(new String(
                      org.bouncycastle.util.encoders.Base64.encode(signedAttributesHash),
                      Charsets.UTF_8)
                  );
  
  </code></pre>
  
  <p>The problems starts around <code>sap.getRangeStream();</code>, the output are different.
  The following variables <code>sh</code> and <code>signedAttributesHash</code> had wrong content. </p>
  
  <p>Did someone manage to do this? Any help would be much appreciated.</p>