title: MakeSignature.signDetached throws No Such Algorithm exception (SUN provider & SHA-256)
body: <p>I am trying to digitally sign a PDF document with iText. Since I will be using a hardware encryptor with JCE provider eventually I am also trying to test getting rid of BountyCastle in my unit test and instead use the default SUN implementation for the time being (until the hardware encryptor arrives).</p>
  
  <p>However, I get the following exception when I run my program:</p>
  
  <p>Exception in thread "main" java.security.NoSuchAlgorithmException: no such algorithm: SHA256 for provider SUN
      at sun.security.jca.GetInstance.getService(GetInstance.java:87)
      at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
      at java.security.Security.getImpl(Security.java:698)
      at java.security.MessageDigest.getInstance(MessageDigest.java:215)
      at com.itextpdf.text.pdf.security.DigestAlgorithms.getMessageDigest(DigestAlgorithms.java:159)
      at com.itextpdf.text.pdf.security.ProviderDigest.getMessageDigest(ProviderDigest.java:61)
      at com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:130)
      at SignDoc.signPdf(SignDoc.java:142)
      at SignDoc.main(SignDoc.java:182)</p>
  
  <p>The last few lines of codes are as below:</p>
  
  <pre><code>    //ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
      //ExternalDigest digest = new BouncyCastleDigest();
      //ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "SUN");
      ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "SunRsaSign");
      ExternalDigest digest = new ProviderDigest("SUN");
      MakeSignature.signDetached(appearance, digest, es, chain, null, null, null, 0, CryptoStandard.CMS);
  </code></pre>
  
  <p>As you can see, I am just copying the samples and changed the provider name and the call 'new BouncyCastleDigest()' to 'new ProviderDigest("SUN")'</p>
  
  <p>Peeking at the source codes of iText (5.5.1-SNAPSHOT), I find the followings code fragments suspicious:</p>
  
  <ol>
  <li><p>MakeSignature.java line 142 - 145</p>
  
  <p><em>hashAlgorithm</em> = externalSignature.getHashAlgorithm() is called and then used in</p>
  
  <p>DigestAlgorithms.digest(data, externalDigest.getMessageDigest(<em>hashAlgorithm</em>));</p></li>
  <li><p>PrivateKeySignature.java line 76</p>
  
  <p>Since I am using PrivateKeySignature, I peek at PrivateKeySignature.java and find that it returns its private class member hashAlgorithm and this is how it obtains the value during Construction (line 76):</p>
  
  <p>this.<em>hashAlgorithm</em> = 
  DigestAlgorithms.getDigest(DigestAlgorithms.getAllowedDigests(<em>hashAlgorithm</em>));</p></li>
  <li><p>DigestAlgorithms.java methods  getAllowedDigests() and getDigest()</p>
  
  <p>In turn, getAllowedDigests() returns the OID of the algorithm if the algorithm name is found in the allowedDigests hash map (2.16.840.1.101.3.4.2.1 in my case), otherwise it returns null. </p>
  
  <p>getDigest gets the digest name back from the OID using the digestNames hash map.</p>
  
  <p>However, the name in digestNames hash map that corresponds to the OID is SHA256, not SHA-256.</p></li>
  </ol>
  
  <p>As a result, the final digest name got was "SHA256" as opposed to "SHA-256" and "SHA256" was causing the NoSuchAlgorithm exception in SUN provider.</p>
  
  <p>(I tried getting a message digest instance directly using the SUN provider. It succeeded for SHA-256 but threw the same exception I am reporting here for SHA256.</p>
  
  <p>Is this a problem with iText when using JCE providers other than BC? </p>
  
  <p>Appreciate if anyone could shed some light on my problem.</p>