title: Signing a SOAP Header with C#
body: <p>I have to use a webservice that requires me to sign the SOAP Header, the resulting XML must look like this:</p>
  
  <pre><code>&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&gt;
      &lt;SOAP-ENV:Header&gt;
          &lt;wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1"&gt;
              &lt;wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId-869FA65AC981B550EF133970680723210" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;MIID0jCCArqgAwIBAgIBBDANBgkqhkiG9w0B...(long Base64 string here)...4a7AXPA==&lt;/wsse:BinarySecurityToken&gt;
              &lt;ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-7"&gt;
                  &lt;ds:SignedInfo&gt;
                      &lt;ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
                      &lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/&gt;
                      &lt;ds:Reference URI="#id-8"&gt;
                          &lt;ds:Transforms&gt;
                              &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
                          &lt;/ds:Transforms&gt;
                          &lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
                          &lt;ds:DigestValue&gt;i6nAseheCMiozKeQRwlJsUDlV8A=&lt;/ds:DigestValue&gt;
                      &lt;/ds:Reference&gt;
                  &lt;/ds:SignedInfo&gt;
                  &lt;ds:SignatureValue&gt;
  i9v0zDtvxu9mH+iPfYoiLL30vMrfgHlcIr9UOtIX1+QcM+nBL0jI+JFcYlNUVgzIFddn/RYxSiGK
  4/amTXHIKxeyI2E/UnX/ajX70t1Pv0boM/i6klZScxmsncgX05ZOQ1AIMLtkSSclK6/vzCFReOmJ
  R6WQs+axGAjF39AqdCQ=
                  &lt;/ds:SignatureValue&gt;
                  &lt;ds:KeyInfo Id="KeyId-869FA65AC981B550EF133970680723311"&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-869FA65AC981B550EF133970680723312" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
                          &lt;wsse:Reference URI="#CertId-869FA65AC981B550EF133970680723210" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/&gt;
                      &lt;/wsse:SecurityTokenReference&gt;
                  &lt;/ds:KeyInfo&gt;
              &lt;/ds:Signature&gt;
          &lt;/wsse:Security&gt;
      &lt;/SOAP-ENV:Header&gt;
      &lt;SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-8"&gt;
          &lt;XmlContent&gt;Some content here&lt;/XmlContent&gt;
      &lt;/SOAP-ENV:Body&gt;
  &lt;/SOAP-ENV:Envelope&gt;
  </code></pre>
  
  <p>Of course, I must sign it following the OASIS specification (<a href="http://docs.oasisopen" rel="nofollow">http://docs.oasisopen</a>.
  org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf).</p>
  
  <p>But I have no idea of where I should start. I'm already able to sign a XML tag, but I never had to sign the SOAP message header following the OASIS specification.</p>
  
  <p>All I need to worry is about creating the SOAP XML message and sign its header, the process of actually sending the SOAP message to the webservice is another thing. We can't consume the webservice directly in Visual Studio, that's why I'm not asking how to actually send it, I just have to create the SOAP message.</p>
  
  <p>Yes, I already have the client's certificate and password, which I can instantiate like this:</p>
  
  <pre><code>X509Certificate2 certificate = new X509Certificate2(this.PfxLocation, this.PfxPassword);
  </code></pre>
  
  <p>I suppose I must create the header string manually, including the wsse:security and all the strings. But as I already said before, I have no idea where to start, where do I get the <code>BinarySecurityToken</code>, how do I add the <code>ds</code> namespace in the signature, among other things.</p>
  
  <p>So, where could I start to resolve this problem? Is there already a solution in C# that I can use? </p>