user575219
user575219

Reputation: 2442

WCF Client Sign only soap body

I did some research on this, but couldn't find a proper solution. Why does my soap request so many reference uri's. The outgoing soap body only should be signed using Private key and encrypted using public key.

My outgoing soap has some additional elements

1)Additional encrypted data node. 2) Additioanal and unreferenced reference URi in Signature

    <s:Security>
    <s:Binarysecuritytoken1>
    <s:Binarysecuirtytoken2>
    <s:usernametoken>

                  <e:EncryptedKey Id="_0" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <o:SecurityTokenReference>
            <o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-c91ddd2c-e452-4616-b443-b58c919bcace-6" />
          </o:SecurityTokenReference>
        </KeyInfo>
        <e:CipherData>
          <e:CipherValue>Wp9slJCs7umXjsMi6diTRB+cSLIADY8RyeNmym7MkfYVxDmP5FIKXwyIV8e7IbLlJEKBUqgIQbYTtwNej7E1PfoD+vI64rOTyxbIhgZ/icnoAIQFJ/Mwuwq60hJhjpfC9m2Ll/S+JsWfg+0Njl+gpYzaECLYeSGEJND6CmbKTUY=</e:CipherValue>
        </e:CipherData>
        <e:ReferenceList>
       <e:DataReference URI="#_2" />
    <e:DataReference URI="#_7" />---Not needed.Only #_2,which references the Body is needed
        </e:ReferenceList>
      </e:EncryptedKey>
---Not needed 
      <e:EncryptedData Id="_7" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
        <e:CipherData>
          <e:CipherValue></e:CipherValue>
        </e:CipherData>
      </e:EncryptedData>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
          <Reference URI="#_1"> Needed
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>l6kqP048t5INzJT3W8gxVSXplaE=</DigestValue>
          </Reference>
          <Reference URI="#_3"> --Not needed
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>r9QXAfEWv2UhmnjzIXyoyHVy9wQ=</DigestValue>
          </Reference>
          <Reference URI="#_4"> --Not needed
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>5JI25GEJj/63MQB6j2P2uiFTwe0=</DigestValue>
          </Reference>
          <Reference URI="#_5"> --Not needed
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>dRaV5csLUbHL6k4X97njcIkwp5k=</DigestValue>
          </Reference>
          <Reference URI="#_6"> --Not needed
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>3c80pnhYcV2BcsEsduxDdQ6z2q0=</DigestValue>
          </Reference>
          <Reference URI="#uuid-131924a6-ba69-4a84-8786-cdbacfe2f79a-2"> --Not needed
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>1fvCyhzU3bILTCoFB8xUnQtP2wA=</DigestValue>
          </Reference>
          <Reference URI="#uuid-c91ddd2c-e452-4616-b443-b58c919bcace-5"> --Not needed
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>LihjfykAPG4wv/HsoKZXjuJ4Eq0=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>removed</SignatureValue>
        <KeyInfo>
          <o:SecurityTokenReference>
            <o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-c91ddd2c-e452-4616-b443-b58c919bcace-7" />
          </o:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </o:Security>

This is the custom Binding

 AsymmetricSecurityBindingElement secBE = AsymmetricSecurityBindingElement.CreateMutualCertificateDuplexBindingElement();
            secBE.AllowSerializedSigningTokenOnReply = false;
            secBE.RequireSignatureConfirmation = true ;
            secBE.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDesRsa15;
           secBE.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
           X509SecurityTokenParameters x509ProtectionParameters = new X509SecurityTokenParameters();
           x509ProtectionParameters.RequireDerivedKeys = false;
           x509ProtectionParameters.X509ReferenceStyle = X509KeyIdentifierClauseType.SubjectKeyIdentifier;
           x509ProtectionParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
           x509ProtectionParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
           secBE.InitiatorTokenParameters = x509ProtectionParameters;
           secBE.RecipientTokenParameters = x509ProtectionParameters;
           secBE.MessageProtectionOrder = MessageProtectionOrder.EncryptBeforeSign;
           secBE.EndpointSupportingTokenParameters.SignedEncrypted.Add(new X509SecurityTokenParameters());
           CustomTextMessageBindingElement enc = new CustomTextMessageBindingElement();
           HttpsTransportBindingElement b = new HttpsTransportBindingElement();
            b.RequireClientCertificate = true;
            CustomBinding be = new CustomBinding();
            be.Elements.Add(secBE);
            be.Elements.Add(enc);
            be.Elements.Add(b);
            return be;

part of Soap sample from vendor. As per my understanding only the Body is signed and encrypted.

<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:Reference URI="#SecurityToken-c0cc2cd4-cb77-4fa5-abfa-bd485afd1685" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>gpBAWt91pdwhKva............</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#Enc-0641b860-b16d-4941-91c0-d60bece67794"/>
</xenc:ReferenceList>
</xenc:EncryptedKey>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
SAMP L E R EQUE ST W I T H WS S E CURI T Y
eMedNY Meds History Service User Guide Page 13 of 48 February 16, 2012
Version 1.1
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#Id-f10674fd-b999-47c9-9568-c11fa5e5405b">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>wRUq.........</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>tBSsaZi........</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#SecurityToken-e00c8062-83d2-4f04-88fc-996218e7bb3d" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body wsu:Id="Id-f10674fd-b999-47c9-9568-c11fa5e5405b" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<xenc:EncryptedData Id="Enc-0641b860-b16d-4941-91c0-d60bece67794" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<xenc:CipherData>
<xenc:CipherValue>SQsTCAK6ZaVhojB8+Y.........</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soapenv:Body>
</soapenv:Envelope>

Edited to show custom EncryptedData, Signature elements

   public static void Encrypt(XmlDocument xmlDoc, string elementToEncrypt, SymmetricAlgorithm ts, XmlNamespaceManager nsmgr, string encdataId) //[8]
        {
            XmlNode elementsToEncrypt = xmlDoc.DocumentElement.SelectSingleNode("/s:Envelope/s:Body", nsmgr);

            XmlElement xmlElementToEncrypt = (XmlElement)elementsToEncrypt;
            EncryptedXml encryptedXml = new EncryptedXml();
            byte[] encryptedElement = encryptedXml.EncryptData
                    (xmlElementToEncrypt,ts, true);

            System.Security.Cryptography.Xml.EncryptedData encryptedData = new System.Security.Cryptography.Xml.EncryptedData();
            encryptedData.Id = encdataId;
            encryptedData.Type = EncryptedXml.XmlEncElementUrl;
            encryptedData.EncryptionMethod =
                new System.Security.Cryptography.Xml.EncryptionMethod(EncryptedXml.XmlEncTripleDESUrl);
            // Create a new CipherData object.
            CipherData cd = new CipherData();
            // Assign a byte array to be the CipherValue. This is a byte array representing encrypted data.
            cd.CipherValue = new byte[8];
            encryptedData.CipherData = cd;
            EncryptedXml.ReplaceElement(xmlElementToEncrypt, encryptedData, true);
        }
        public void SignSoapBody(XmlDocument xmlDoc, XmlNode xmlnodeEncKey, string encdataId)
        {
            XmlNamespaceManager nsmgr =
                           new XmlNamespaceManager(xmlDoc.NameTable);
            nsmgr.AddNamespace("s",
                 @"http://www.w3.org/2000/09/xmldsig#");
            X509Certificate2 cert = GetCertificateFromStore("LMWARD");
            string refURI = DateTime.Now.Ticks.ToString();

            // *** Signed XML will create Xml Signature - Xml fragment
            SignedXml signedXml = new SignedXml(xmlDoc);
            signedXml.SigningKey = cert.PrivateKey;
            // *** Create a KeyInfo structure
            KeyInfo keyInfo = new KeyInfo();

            KeyInfoX509Data keyInfoData = new KeyInfoX509Data();
            keyInfoData.AddCertificate(cert);
            keyInfo.AddClause(keyInfoData);
            signedXml.KeyInfo = keyInfo;

            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl;
            // *** Now create reference to sign: Point at the Body element

            Reference reference = new Reference();
            reference.Uri = "#"+ encdataId;  // reference id=body section in same doc
            reference.AddTransform(new XmlDsigExcC14NTransform());  // required to match doc
            signedXml.AddReference(reference);
            // *** Finally create the signature
            signedXml.ComputeSignature();
            XmlElement signedElement = signedXml.GetXml();
            XmlNode SignatureNode = xmlDoc.CreateNode(XmlNodeType.Element, "Signature", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            SignatureNode.InnerXml = signedElement.InnerXml;
            // *** And add our signature as content

            XmlNode commonParent = xmlnodeEncKey.ParentNode;
           commonParent.InsertAfter(SignatureNode, xmlnodeEncKey);

        }

Actually the encrypted data method encrypts the soap body, adds a reference ID. i would need some help on the SignSoapBody(...). It needs a SecurityTokenReference inside the KeyInfo element,and moreover different Canonicalization algorithm. It is totally not writing what is needed. See above for how the request should look like.
THis is what it actually writes to the Signature (My code generates the following signature)

 <Signature xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
          <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
          <Reference URI="#635077936132736291">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>NUOpt38t11pdL0wAPiyFthhYM9Q=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#">kNXiSoBMOeEuoKhUQzuJddNzPrSGxFZIyj0QIp0ngmEbUwQXP25loZBKtX6QB/l913ZX5PGgU7IwCsVjuiCluqqtEGEy7V03gqSKpY+Iz45Md+kyazrfDXDVnPNIZKN8p8K+0QhJmqWA0r1K/sjyYldNiJJd8d12gIRPtDEVGPU=</SignatureValue>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <X509Data>
            <X509Certificate>=</X509Certificate>
          </X509Data>
        </KeyInfo>
      </Signature>

Edited 06/26

 <e:EncryptedKey Id="_0" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
    <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
    <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
      <o:SecurityTokenReference>
        <o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="fgsgsd2cc312a052f-6" />
      </o:SecurityTokenReference>
    </KeyInfo>
    <e:CipherData>
      <e:CipherValue></e:CipherValue>
    </e:CipherData>
    <e:ReferenceList>
      <e:DataReference URI="#_2" />
      <e:DataReference URI="#_3" />---NOT NEEDE---
    </e:ReferenceList>
  </e:EncryptedKey>
---NOT NEEDED---
  <e:EncryptedData Id="_3" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
    <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
    <e:CipherData>

Thank you Sun

Upvotes: 2

Views: 2451

Answers (1)

Yaron Naveh
Yaron Naveh

Reputation: 24396

Change MessageSecurityVersion to a value that starts with WSSecurity10

Upvotes: 1

Related Questions