title: Xml Signature for XmlElement fails to verify
body: <p>I apologize in advance for the rather lengthy block of code, but it's the smallest compilable example I could produce. I already omitted all error checking from the original code. I'm using Visual Studio 2012 and .NET 4.5, although this is nothing new to 4.5, it should work with any version.</p>
  
  <p>I am trying to sign an XML documents' elements to protect them from tampering. I don't want to protect the whole document, but only certain elements. Maybe even different elements with different keys. </p>
  
  <p>However, when I sign three example elements and try to verify them, the first one always verifies, the other two fail. To make it even worse, the first one even succeeds if I modify it after being signed. I have googled a lot, read a lot of tutorials and even <a href="https://stackoverflow.com/questions/16479018/signing-xml-elements-in-same-document-with-different-keys">asked a theoretical question here</a>, but I don't have any clue what I'm doing wrong. Can anybody spot my mistake?</p>
  
  <p>Note: I'd be more than happy to offer the same bounty that's on friday's question to anybody solving this.</p>
  
  <p>The certificate was created by executing:</p>
  
  <blockquote>
    <p>"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\makecert" -r -pe -n "CN=XMLDSIG_Test" -b 01/01/2013 -e 01/01/2014 -sky signing -ss my</p>
  </blockquote>
  
  <p>The Test xml file is:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;PackageRoot&gt;
    &lt;Package&gt;
      &lt;Changes &gt;
       &lt;Change/&gt;
      &lt;/Changes&gt;
    &lt;/Package&gt;
    &lt;Package&gt;
      &lt;Changes&gt;
       &lt;Change/&gt;
       &lt;Change/&gt;
      &lt;/Changes&gt;
    &lt;/Package&gt;
    &lt;Package&gt;
      &lt;Changes&gt;
       &lt;Change/&gt;
       &lt;Change/&gt;
       &lt;Change/&gt;
      &lt;/Changes&gt;
    &lt;/Package&gt;
  &lt;/PackageRoot&gt;
  </code></pre>
  
  <p>The code to sign and verify:</p>
  
  <pre><code>namespace SOExample
  {
    using System;
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Cryptography.Xml;
    using System.Xml;
  
    public static class Program
    {
      public static void Sign(this XmlElement element, X509Certificate2 certificate)
      {
          var identifier = Guid.NewGuid().ToString();
  
          element.SetAttribute("Id", identifier);
  
          var signedXml = new SignedXml(element) { SigningKey = certificate.PrivateKey };
  
          var reference = new Reference("#" + identifier);
  
          reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
  
          signedXml.AddReference(reference);
  
          signedXml.ComputeSignature();
  
          var xmlDigitalSignature = signedXml.GetXml();
  
          element.AppendChild(element.OwnerDocument.ImportNode(xmlDigitalSignature, true));
      }
  
      public static bool VerifySignature(this XmlElement element, X509Certificate2 certificate)
      {
        var signedXml = new SignedXml(element);
  
        XmlNodeList nodeList = element.GetElementsByTagName("Signature");
  
        if (nodeList.Count != 1) return false;
  
        signedXml.LoadXml((XmlElement)nodeList[0]);
  
        return signedXml.CheckSignature(certificate, true);
      }
  
      public static void Main()
      {
          var xmlDoc = new XmlDocument { PreserveWhitespace = true };
  
          xmlDoc.Load("ExamplePackage.xml");
  
          var certificate = GetCertificateBySubject("CN=XMLDSIG_Test");
  
          foreach (XmlElement root in xmlDoc.GetElementsByTagName("PackageRoot"))
          {
            foreach (XmlElement package in root.GetElementsByTagName("Package"))
            {
              package.Sign(certificate);
            }
          }
  
          xmlDoc.Save("test_signed.xml");
  
          Console.WriteLine("XML file signed.");
          Console.WriteLine("Press any key to verify");
          Console.ReadLine();
  
          var signedDoc = new XmlDocument();
  
          signedDoc.Load("test_signed.xml");
  
          foreach (XmlElement root in xmlDoc.GetElementsByTagName("PackageRoot"))
          {
            foreach (XmlElement package in root.GetElementsByTagName("Package"))
            {
              Console.Write("Verifying Package " + package.GetAttribute("Id"));
              var success = package.VerifySignature(certificate);
              Console.WriteLine(success ? " successful!" : " failed!");
            }
          }
  
          Console.WriteLine("Done.");
          Console.ReadLine();
      }
  
      private static X509Certificate2 GetCertificateBySubject(string certificateSubject)
      {
        var store = new X509Store("My", StoreLocation.CurrentUser);
  
        store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
  
        foreach (X509Certificate2 c in store.Certificates)
        {
          if (c.Subject == certificateSubject)
          {
            store.Close();
            return c;
          }
        }
  
        store.Close();
        return null;
      }
    }
  }
  </code></pre>