title: Signing SOAP Message with XML Signature and WCF
body: <p>Currently I'm implementing a client in .NET to consume a SOAP service written in JAVA (I'm not sure). The SOAP envelope has to be signed in a very specific way, and it has been a nightmare trying to do so.</p>
  
  <p>This is an example of the envelope they are expecting:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
      &lt;soapenv:Header&gt;
          &lt;wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"&gt;
              &lt;ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
                  &lt;ds:SignedInfo&gt;
                      &lt;ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;&lt;/ds:CanonicalizationMethod&gt;
                      &lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"&gt;&lt;/ds:SignatureMethod&gt;
                      &lt;ds:Reference URI="#id-319644606"&gt;
                          &lt;ds:Transforms&gt;
                              &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;&lt;/ds:Transform&gt;
                          &lt;/ds:Transforms&gt;
                          &lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"&gt;&lt;/ds:DigestMethod&gt;
                          &lt;ds:DigestValue&gt;uQpjnTTrxxI7ck9FpeEI6YRVHBA=&lt;/ds:DigestValue&gt;
                      &lt;/ds:Reference&gt;
                  &lt;/ds:SignedInfo&gt;
                  &lt;ds:SignatureValue&gt;
  paNzJWyYDBNTj8Ay4z0/wOKKQUCe/z0q/LRcDgB9CP1fn/FZW8uyLdASHxs2HHlpYG7daFvbtpsQ
  ZoiIUSzUuUBUAjjaqLWRZyUeCqc48f8X6vxR52mLARnJdPC9MWPZg8FTsoqJ2nvyH28chqf8Svql
  KxgtCtBiL9wPnkzG5m4=
  &lt;/ds:SignatureValue&gt;
                  &lt;ds:KeyInfo Id="KeyId-1827725498"&gt;
                      &lt;wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-131635550"&gt;
                          &lt;ds:X509IssuerSerial&gt;
                              &lt;ds:X509IssuerName&gt;CN=DESARROLLO,OU=INGENIERIA,O=ASOBANCARIA,L=BOGOTA,ST=D.C,C=CO&lt;/ds:X509IssuerName&gt;
                              &lt;ds:X509SerialNumber&gt;1141316577&lt;/ds:X509SerialNumber&gt;
                          &lt;/ds:X509IssuerSerial&gt;
                      &lt;/wsse:SecurityTokenReference&gt;
                  &lt;/ds:KeyInfo&gt;
              &lt;/ds:Signature&gt;
              &lt;wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
                  &lt;wsu:Created&gt;2014-10-29T22:14:01Z&lt;/wsu:Created&gt;
                  &lt;wsu:Expires&gt;2014-10-29T22:19:01Z&lt;/wsu:Expires&gt;
              &lt;/wsu:Timestamp&gt;
          &lt;/wsse:Security&gt;
      &lt;/soapenv:Header&gt;
      &lt;soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-319644606"&gt;
          &lt;ns1:evaluarCuestionario xmlns:ns1="http://ws.confrontaultra.cifin.asobancaria.com" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;
              &lt;p_parametrosSeguridad href="#id0"&gt;&lt;/p_parametrosSeguridad&gt;
              &lt;p_respuestaCuestionario href="#id1"&gt;&lt;/p_respuestaCuestionario&gt;
          &lt;/ns1:evaluarCuestionario&gt;
          &lt;multiRef xmlns:ns2="http://ultras.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:RespuestaCuestionarioULTRADTO"&gt;
              &lt;secuenciaCuestionario href="#id2"&gt;&lt;/secuenciaCuestionario&gt;
              &lt;codigoCuestionario href="#id3"&gt;&lt;/codigoCuestionario&gt;
              &lt;respuestas xmlns:ns3="http://ultra.dto.confrontaultra.cifin.co" soapenc:arrayType="ns3:RespuestaPreguntaULTRADTO[5]" xsi:type="soapenc:Array"&gt;
                  &lt;respuestas href="#id4"&gt;&lt;/respuestas&gt;
                  &lt;respuestas href="#id5"&gt;&lt;/respuestas&gt;
                  &lt;respuestas href="#id6"&gt;&lt;/respuestas&gt;
                  &lt;respuestas href="#id7"&gt;&lt;/respuestas&gt;
                  &lt;respuestas href="#id8"&gt;&lt;/respuestas&gt;
              &lt;/respuestas&gt;
          &lt;/multiRef&gt;
          &lt;multiRef xmlns:ns4="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns4:ParametrosSeguridadULTRADTO"&gt;
              &lt;claveCIFIN xsi:type="soapenc:string"&gt;90681&lt;/claveCIFIN&gt;
              &lt;password xsi:type="soapenc:string"&gt;H32std&lt;/password&gt;
          &lt;/multiRef&gt;
          &lt;multiRef xmlns:ns5="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id7" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns5:RespuestaPreguntaULTRADTO"&gt;
              &lt;secuenciaPregunta href="#id9"&gt;&lt;/secuenciaPregunta&gt;
              &lt;secuenciaRespuesta href="#id10"&gt;&lt;/secuenciaRespuesta&gt;
          &lt;/multiRef&gt;
          &lt;multiRef xmlns:ns6="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id4" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns6:RespuestaPreguntaULTRADTO"&gt;
              &lt;secuenciaPregunta href="#id11"&gt;&lt;/secuenciaPregunta&gt;
              &lt;secuenciaRespuesta href="#id12"&gt;&lt;/secuenciaRespuesta&gt;
          &lt;/multiRef&gt;
          &lt;multiRef xmlns:ns7="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id6" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns7:RespuestaPreguntaULTRADTO"&gt;
              &lt;secuenciaPregunta href="#id13"&gt;&lt;/secuenciaPregunta&gt;
              &lt;secuenciaRespuesta href="#id14"&gt;&lt;/secuenciaRespuesta&gt;
          &lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id2" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:long"&gt;8846263&lt;/multiRef&gt;
          &lt;multiRef xmlns:ns8="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id5" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns8:RespuestaPreguntaULTRADTO"&gt;
              &lt;secuenciaPregunta href="#id15"&gt;&lt;/secuenciaPregunta&gt;
              &lt;secuenciaRespuesta href="#id16"&gt;&lt;/secuenciaRespuesta&gt;
          &lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id3" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;7062&lt;/multiRef&gt;
          &lt;multiRef xmlns:ns9="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id8" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns9:RespuestaPreguntaULTRADTO"&gt;
              &lt;secuenciaPregunta href="#id17"&gt;&lt;/secuenciaPregunta&gt;
              &lt;secuenciaRespuesta href="#id18"&gt;&lt;/secuenciaRespuesta&gt;
          &lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id12" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;150136315&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id14" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;150136266&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id17" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;7&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id10" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;150136259&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id16" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;150136277&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id9" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;20&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id18" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;150136247&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id15" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;35&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id13" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;9&lt;/multiRef&gt;
          &lt;multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id11" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int"&gt;92&lt;/multiRef&gt;
      &lt;/soapenv:Body&gt;
  &lt;/soapenv:Envelope&gt;
  </code></pre>
  
  <p>So basically I have 2 problems:</p>
  
  <ol>
  <li>I haven't been able to set the proper namespaces to the signature header. (the ds namespace)</li>
  <li><p>Also, notice the wsse:SecutiryTokenReference tag inside the KeyInfo tag. The SignedXml class generates this xml by default inside the KeyInfo element:</p>
  
  <pre><code>&lt;KeyInfo&gt;
      &lt;X509Data&gt;
           &lt;X509IssuerSerial&gt;
               &lt;X509IssuerName&gt;CN=RootCATest&lt;/X509IssuerName&gt;
               &lt;X509SerialNumber&gt;228801528337358580231830876343013017805&lt;/X509SerialNumber&gt;
           &lt;/X509IssuerSerial&gt;
      &lt;/X509Data&gt;
  &lt;/KeyInfo&gt;
  </code></pre></li>
  </ol>
  
  <p>So, how can I replace this <code>&lt;X509Data&gt;</code> element with <code>&lt;wsse:SecurityTokenReference&gt;</code> element.</p>
  
  <p>So far I made an implementation following lots of posts and blogs I've found in order to sign the xml document. This is my implementation:</p>
  
  <pre><code> public class Signer
      {
          public XmlDocument SignMessage(XmlDocument xmlDoc, X509Certificate2 certificate)
          {
              var ns = new XmlNamespaceManager(xmlDoc.NameTable);
              ns.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
  
              var body = xmlDoc.DocumentElement.SelectSingleNode(@"//soapenv:Body", ns) as XmlElement;
              if (body == null)
                  throw new ApplicationException("No body tag found");
              body.SetAttribute("id", "Body");
  
              var signedXml = new SignedXml(xmlDoc);
  
              var keyInfo = new KeyInfo();
              signedXml.SigningKey = certificate.PrivateKey;                
  
              var keyInfoData = new KeyInfoX509Data();
              keyInfoData.AddIssuerSerial(certificate.Issuer, certificate.GetSerialNumberString());
              keyInfo.AddClause(keyInfoData);    
  
              signedXml.KeyInfo = keyInfo;
  
              signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
              var reference = new Reference { Uri = "#Body" };
  
              reference.AddTransform(new XmlDsigExcC14NTransform());
              signedXml.AddReference(reference);
              signedXml.ComputeSignature();
  
              var signedElement = signedXml.GetXml();
  
              var securityNode = xmlDoc.CreateElement(
                  "wsse",
                  "Security",
                  "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
  
              securityNode.AppendChild(signedElement);
  
              var timeStampNOde = xmlDoc.CreateElement("Timestamp");
              var createdNode = xmlDoc.CreateElement("Created");
              createdNode.InnerText = JsonConvert.SerializeObject(DateTime.UtcNow, new IsoDateTimeConverter());
              var expiresNode = xmlDoc.CreateElement("Created");
              expiresNode.InnerText = JsonConvert.SerializeObject(DateTime.UtcNow.AddMinutes(5), new IsoDateTimeConverter());
              timeStampNOde.AppendChild(createdNode);
              timeStampNOde.AppendChild(expiresNode);
  
              securityNode.AppendChild(timeStampNOde);
  
              var soapHeader = xmlDoc.DocumentElement.SelectSingleNode(@"//soapenv:Header", ns) as XmlElement;
              if (soapHeader == null)
              {
                  soapHeader = xmlDoc.CreateElement("soapenv:Header", "");
                  xmlDoc.DocumentElement.InsertBefore(soapHeader, xmlDoc.DocumentElement.ChildNodes[0]);
              }
              soapHeader.AppendChild(securityNode);
  
              return xmlDoc;
          }
  </code></pre>
  
  <p>Any comments, suggestions, posts, etc would be very helpful. Consider I have to send the the envelope as they require, since this organization won't change it just for me, I'm guessing they have tons of clients.</p>
  
  <p>Thank you very much!</p>