title: XML Signature validation failing in some messages and passing on others
body: <p>I have a java application that checks in with a .NET server for licensing purposes. The licensing server responds with signed xml. For some messages the Java application fails to validate the signature, but for others it works fine.</p>
  
  <p>Here is a message that is able to be validated with no problem (formatted and replaced sensitive data):</p>
  
  <pre><code>&lt;AuthorizeResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance"&gt;
      &lt;LicenseKey&gt;replaced actual data&lt;/LicenseKey&gt;
      &lt;Message i:nil="true" /&gt;
      &lt;MessageGuid&gt;67d5b7bd-33bd-467b-a3fc-842f0f4782e3&lt;/MessageGuid&gt;
      &lt;Nonce&gt;0&lt;/Nonce&gt;
      &lt;Success&gt;true&lt;/Success&gt;
      &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/2000/09/xmldsig#rsa-sha1" /&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/2000/09/xmldsig#sha1" /&gt;
                  &lt;DigestValue&gt;QQL4nxJbna/VUR/b3caorWjHb0Q=&lt;/DigestValue&gt;
              &lt;/Reference&gt;
          &lt;/SignedInfo&gt;
          &lt;SignatureValue&gt;
              nui/m6DvMBbKjncklq1/1Bo4Bzq8C1Z+dhL0c3YMM2wDdDMhC7ob201r3XnDijFcuhz8BomNbE2Br51Y9+R1wPq2JuQ0K8037f7WmQW5M1l+5Dvz9bFrK1oKExKudg9iRNv0iYcgMxY6x0m3tyQTC6KnH/uBtALbQeNLTti+ho4=
          &lt;/SignatureValue&gt;
      &lt;/Signature&gt;
  &lt;/AuthorizeResponse&gt;
  </code></pre>
  
  <p>Here is a message where validation fails (formatted):</p>
  
  <pre><code>&lt;AuthorizeResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance"&gt;
      &lt;LicenseKey i:nil="true" /&gt;
      &lt;Message&gt;Already using license on max number of systems. Running on
          systems:127.0.0.1;192.168.1.8;host.docker.internal;1127.0.0.1;192.168.1.8;host.docker.internal;2&lt;/Message&gt;
      &lt;MessageGuid&gt;7f5d0e32-6117-4204-85e1-dec5c57c053e&lt;/MessageGuid&gt;
      &lt;Nonce&gt;0&lt;/Nonce&gt;
      &lt;Success&gt;false&lt;/Success&gt;
      &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/2000/09/xmldsig#rsa-sha1" /&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/2000/09/xmldsig#sha1" /&gt;
                  &lt;DigestValue&gt;JJ81DxbusvrVSCZUy/3nobs71FU=&lt;/DigestValue&gt;
              &lt;/Reference&gt;
          &lt;/SignedInfo&gt;
          &lt;SignatureValue&gt;
              aYhs9Vri70bSqsRcVyE8HpQgs0KIQQfmTgJiIv2QzP4Aa172T5ntiii0EU4CJn28N3tXSJK4wmbxZBOvZGnyYuBOv/5jWEFyeUuNAwmw/r+HdVKctBD0BRmSSq+fqQpMjlJmyT/3RL1S250KhCFB05NhvSxk0IbZUei/4RpWwcc=
          &lt;/SignatureValue&gt;
      &lt;/Signature&gt;
  &lt;/AuthorizeResponse&gt;
  </code></pre>
  
  <p>Signing code in C#:</p>
  
  <pre><code>        public static void SignXmlDocument(string privateKey, XmlDocument xmlDoc)
          {
              SignedXml signedXml = new SignedXml(xmlDoc);
  
              RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
              rsaKey.FromXmlString(privateKey);
              signedXml.SigningKey = rsaKey;
  
              Reference reference = new Reference {Uri = ""};
              XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
              reference.AddTransform(env);
              signedXml.AddReference(reference);
              signedXml.ComputeSignature();
              XmlElement xmlDigitalSignature = signedXml.GetXml();
              // ReSharper disable once PossibleNullReferenceException
              xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
          }
  </code></pre>
  
  <p>Validation code in Java (<code>jboss</code> is false):</p>
  
  <pre><code>    private static boolean verifyXmlFromStream(InputStream SignedXmlDocumentStream, boolean jboss)
      {
          try
          {
              DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
              dbf.setNamespaceAware(true);
              Document sourceDoc = dbf.newDocumentBuilder().parse(SignedXmlDocumentStream);
  
              NodeList nl = sourceDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
              if (nl.getLength() == 0)
                  throw new Exception("Cannot find Signature element");
  
              XMLSignatureFactory factory = getSignatureFactory(jboss);
              DOMValidateContext valContext = new DOMValidateContext(new KeyValueKeySelector(), nl.item(0));
              XMLSignature signature = factory.unmarshalXMLSignature(valContext);
              boolean coreValidity = signature.validate(valContext);
  
              if (!coreValidity)
                  log.warn("Signature failed core validation!"); // error?
              return coreValidity;
          }
          catch (Exception e)
          {
              log.error(e);
              return false;
          }
      }
  
      private static XMLSignatureFactory getSignatureFactory(boolean jboss)
          throws ClassNotFoundException,
                 InstantiationException,
                 IllegalAccessException
      {
          if (jboss)
          {
              log.debug("Getting XML security provider using JBoss friendly method.");
              return XMLSignatureFactory.getInstance("DOM");
          }
          else
          {
              String provider = System.getProperty("jsr105Provider",
                      "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
              return XMLSignatureFactory.getInstance("DOM",
                      (Provider)Class.forName(provider).newInstance());
          }
      }
  </code></pre>
  
  <p>Any idea why signing is working correctly for some messages and failing with others? I've tried encoding the document differently and sending the second message without the ';' character with no difference in behavior.</p>
  
  <p>Edit: I've also tried building the HttpContent returned by my server in several different ways in case some white space formatting was changing when I built my StringContent.</p>