title: Unable to validate SHA 256 Xml Signature using Java
body: <p>I Have one xml which is signed by following signinfo</p>
  
  <p><strong>XML</strong></p>
  
  <pre><code>&lt;SignedInfo&gt;
           &lt;CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /&gt;
           &lt;SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /&gt;
           &lt;Reference URI=""&gt;
              &lt;Transforms&gt;
                 &lt;Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /&gt;
              &lt;/Transforms&gt;
              &lt;DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /&gt;
              &lt;DigestValue&gt;XYZ&lt;/DigestValue&gt;
           &lt;/Reference&gt;
        &lt;/SignedInfo&gt;
  </code></pre>
  
  <p>I would like to verify my signature which is coming from trusted source.
  I have signature value and Keyinfo with me.</p>
  
  <p>For Example :</p>
  
  <pre><code>&lt;SignatureValue&gt;XYZ&lt;/SignatureValue&gt;
        &lt;KeyInfo&gt;
           &lt;KeyValue&gt;
              &lt;RSAKeyValue&gt;
                 &lt;Modulus&gt;ABC&lt;/Modulus&gt;
                 &lt;Exponent&gt;XYX&lt;/Exponent&gt;
              &lt;/RSAKeyValue&gt;
           &lt;/KeyValue&gt;
        &lt;/KeyInfo&gt;
  </code></pre>
  
  <p>All in All my Signature tag looks like this</p>
  
  <p><strong>XML</strong></p>
  
  <pre><code>&lt;Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&gt;
        &lt;SignedInfo&gt;
           &lt;CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /&gt;
           &lt;SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /&gt;
           &lt;Reference URI=""&gt;
              &lt;Transforms&gt;
                 &lt;Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /&gt;
              &lt;/Transforms&gt;
              &lt;DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /&gt;
              &lt;DigestValue&gt;XYZ&lt;/DigestValue&gt;
           &lt;/Reference&gt;
        &lt;/SignedInfo&gt;
        &lt;SignatureValue&gt;XYZ&lt;/SignatureValue&gt;
            &lt;KeyInfo&gt;
               &lt;KeyValue&gt;
                  &lt;RSAKeyValue&gt;
                     &lt;Modulus&gt;ABC&lt;/Modulus&gt;
                     &lt;Exponent&gt;XYX&lt;/Exponent&gt;
                  &lt;/RSAKeyValue&gt;
               &lt;/KeyValue&gt;
            &lt;/KeyInfo&gt;
     &lt;/Signature&gt;
  </code></pre>
  
  <p>To Verify Signature I used a lot of methods but I could not verify Signature with SHA256 Algo.</p>
  
  <p><strong>Java</strong></p>
  
  <pre><code>import java.io.FileInputStream;
  import java.security.Key;
  import java.security.KeyException;
  import java.security.PublicKey;
  import java.security.cert.X509Certificate;
  import java.util.Iterator;
  import java.util.List;
  
  import javax.xml.crypto.AlgorithmMethod;
  import javax.xml.crypto.KeySelector;
  import javax.xml.crypto.KeySelectorException;
  import javax.xml.crypto.KeySelectorResult;
  import javax.xml.crypto.XMLCryptoContext;
  import javax.xml.crypto.XMLStructure;
  import javax.xml.crypto.dsig.Reference;
  import javax.xml.crypto.dsig.SignatureMethod;
  import javax.xml.crypto.dsig.XMLSignature;
  import javax.xml.crypto.dsig.XMLSignatureFactory;
  import javax.xml.crypto.dsig.dom.DOMValidateContext;
  import javax.xml.crypto.dsig.keyinfo.KeyInfo;
  import javax.xml.crypto.dsig.keyinfo.KeyValue;
  import javax.xml.crypto.dsig.keyinfo.X509Data;
  import javax.xml.parsers.DocumentBuilderFactory;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.NodeList;
  
  /**
   * This is a simple example of validating an XML Signature using the JSR 105
   * API. It assumes the key needed to validate the signature is contained in a
   * KeyValue KeyInfo.
   */
  public class Validate {
  
      //
      // Synopsis: java Validate [document]
      //
      // where "document" is the name of a file containing the XML document
      // to be validated.
      //
      public static void main(String[] args) throws Exception {
          String fileName = "signedXMl.xml";
  
          // Instantiate the document to be validated 
          DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
          dbf.setNamespaceAware(true);
          Document doc = dbf.newDocumentBuilder().parse(
                  new FileInputStream(fileName));
  
          // Find Signature element
          NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS,
                  "Signature");
          if (nl.getLength() == 0) {
              throw new Exception("Cannot find Signature element");
          }
  
          // Create a DOM XMLSignatureFactory that will be used to unmarshal the
          // document containing the XMLSignature
          XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
  
          // Create a DOMValidateContext and specify a KeyValue KeySelector
          // and document context
          DOMValidateContext valContext = new DOMValidateContext(
                  new KeyValueKeySelector(), nl.item(0));
  
          // unmarshal the XMLSignature
          XMLSignature signature = fac.unmarshalXMLSignature(valContext);
  
          // Validate the XMLSignature (generated above)
          boolean coreValidity = signature.validate(valContext);
  
          // Check core validation status
          if (coreValidity == false) {
              System.err.println("Signature failed core validation");
              boolean sv = signature.getSignatureValue().validate(valContext);
              System.out.println("signature validation status: " + sv);
              // check the validation status of each Reference
              Iterator&lt;?&gt; i = signature.getSignedInfo().getReferences().iterator();
              for (int j = 0; i.hasNext(); j++) {
                  boolean refValid = ((Reference) i.next()).validate(valContext);
                  System.out.println("ref[" + j + "] validity status: "
                          + refValid);
              }
          } else {
              System.out.println("Signature passed core validation");
          }
      }
  
      /**
       * KeySelector which retrieves the public key out of the KeyValue element
       * and returns it. NOTE: If the key algorithm doesn't match signature
       * algorithm, then the public key will be ignored.
       */
      private static class KeyValueKeySelector extends KeySelector {
          public KeySelectorResult select(KeyInfo keyInfo,
                  KeySelector.Purpose purpose, AlgorithmMethod method,
                  XMLCryptoContext context) throws KeySelectorException {
  
              if (keyInfo == null) {
                  throw new KeySelectorException("Null KeyInfo object!");
              }
              SignatureMethod sm = (SignatureMethod) method;
              List&lt;?&gt; list = keyInfo.getContent();
  
              for (int i = 0; i &lt; list.size(); i++) {
                  XMLStructure xmlStructure = (XMLStructure) list.get(i);
                  if (xmlStructure instanceof X509Data) {
                      PublicKey pk = null;
                      List&lt;?&gt; l = ((X509Data) xmlStructure).getContent();
                      if (l.size() &gt; 0) {
                          X509Certificate cert = (X509Certificate) l.get(0);
                          pk = cert.getPublicKey();
                          if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
                              return new SimpleKeySelectorResult(pk);
                          }
                      }
                  }
                  if (xmlStructure instanceof KeyValue) {
                      PublicKey pk = null;
                      try {
                          pk = ((KeyValue) xmlStructure).getPublicKey();
                      } catch (KeyException ke) {
                          throw new KeySelectorException(ke);
                      }
                      // make sure algorithm is compatible with method
                      if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
                          return new SimpleKeySelectorResult(pk);
                      }
                  }
              }
              throw new KeySelectorException("No KeyValue element found!");
          }
  
          // @@@FIXME: this should also work for key types other than DSA/RSA
          static boolean algEquals(String algURI, String algName) {
              if (algName.equalsIgnoreCase("DSA") &amp;&amp; algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
                  return true;
              } else if (algName.equalsIgnoreCase("RSA")
                      &amp;&amp; algURI.equalsIgnoreCase("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")) {
                  return true;
              } else {
                  return false;
              }
          }
      }
  
      private static class SimpleKeySelectorResult implements KeySelectorResult {
          private PublicKey pk;
  
          SimpleKeySelectorResult(PublicKey pk) {
              this.pk = pk;
          }
  
          public Key getKey() {
              return pk;
          }
      }
  }
  </code></pre>