StickyMcGinty
StickyMcGinty

Reputation: 445

WCF - How to debug "The signature verification failed" messages

I've created a WCF client that is calling a Spring Web Services 2.1.0 + Apache WSS4J 1.6.7 (WS-Sec 1.1) server and returning a response.

WCF is complaining that the "Message security verification failed" with an InnerException of "The signature verification failed"

Problem is, I've no other way of debugging this as it's on a production server. I've got WCF logging the SOAP going to and from and the exceptions being thrown, and the guys who run the server say they can process responses fine on their end (i.e. they dont get a problem verifying the signature )

Any idea's on how to debug this further? Would I be able to create a console app to validate the SOAP?

I've been able to send requests through to their server OK and am getting responses so I've been trying to validate this via a console app so that I can see where the response is going wrong, but cant get the Console app to verify the XML either - CheckSignature is always returning false when I run the request and response through.

Note: I've tried setting xmlDoc.PreserveWhitespace as true and false

Any help at all is appreciated

Just to note also - the code below is just something I put together to test the signature. The actual service binding / service client is a seperate app. The binding for this is below:

<customBinding>
        <binding name="MY_BINDING">
          <transactionFlow/>
          <security defaultAlgorithmSuite="Basic256Rsa15" authenticationMode="MutualCertificate"
                    messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"
                    requireDerivedKeys="false" messageProtectionOrder="SignBeforeEncrypt" 
                    allowSerializedSigningTokenOnReply="true" securityHeaderLayout="Lax" >
            <secureConversationBootstrap authenticationMode="CertificateOverTransport"
                                         messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
                                         requireDerivedKeys="false" />
          </security>
          <textMessageEncoding messageVersion="Soap11WSAddressing10"/>
          <httpsTransport requireClientCertificate="true"/>
        </binding>
      </customBinding>

Binding from code - Config XML binding is retrieved and modified

public static CustomBinding GetServiceBinding()
        {            
            //Get custom binding reference from app.config
            CustomBinding binding = new CustomBinding(SettingsLookup.WcfCustomBindingName);
            binding.ReceiveTimeout = new TimeSpan(0, 0, 15, 0);
            binding.SendTimeout = new TimeSpan(0, 0, 15, 0);

            // Get the x509ProtectionParams from the security element
            X509SecurityTokenParameters tokenParameters = new X509SecurityTokenParameters();
            tokenParameters.X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial;
            tokenParameters.RequireDerivedKeys = false;
            tokenParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;

            // Reference the asymettric security element            
            AsymmetricSecurityBindingElement securityBindingElement = binding.Elements.Find<AsymmetricSecurityBindingElement>();
            // Set the X509SecurityTokenParameters to point to the one's just configured. This is for symetric encryption, for asymetric this line needs to change
            //securityBindingElement.ProtectionTokenParameters = tokenParameters;
            securityBindingElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
            securityBindingElement.InitiatorTokenParameters = tokenParameters;
            securityBindingElement.LocalClientSettings.DetectReplays = false;
            securityBindingElement.RequireSignatureConfirmation = true;
            //Set timestamp to false as it's not in the VHI request
            securityBindingElement.IncludeTimestamp = true;
            securityBindingElement.LocalClientSettings.TimestampValidityDuration = new TimeSpan(12,0,0);




            return binding;
        }

This app is just for checking the signature i was feeding in the SOAP envelope directly in a hope to debug the signature and see what was failing

// TEST PROGRAM JUST FOR CHECKING SIGNATURE, CONSOLE APP SEPERATE FROM MAIN APP
class Program
        {
            static void Main(string[] args)
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.PreserveWhitespace = true;
                xmlDoc.LoadXml(Resource1.request);

                X509Certificate2 cert = new X509Certificate2(@"D:\TEMP\certs\pub_and_private_key.pfx", "password");

                bool result = ValidateSoapBodySignature(xmlDoc, cert);

            }

        public static bool ValidateSoapBodySignature(XmlDocument doc, X509Certificate2 cert)
        {
            // *** Load the doc this time
            SignedXmlWithId sdoc = new SignedXmlWithId(doc);

            // *** Find the signature and load it into SignedXml
            XmlNodeList nodeList = doc.GetElementsByTagName("Signature", "http://www.w3.org/2000/09/xmldsig#");
            sdoc.LoadXml((XmlElement)nodeList[0]);

            // *** Now read the actual signature and validate
            bool result = sdoc.CheckSignature(cert, true);

            return result;
        }


    }

    public class SignedXmlWithId : SignedXml
    {
        public SignedXmlWithId(XmlDocument xml)
            : base(xml)
        {
        }

        public SignedXmlWithId(XmlElement xmlElement)
            : base(xmlElement)
        {
        }

        public override XmlElement GetIdElement(XmlDocument doc, string id)
        {
            // check to see if it's a standard ID reference
            XmlElement idElem = base.GetIdElement(doc, id);

            if (idElem == null)
            {
                XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
                nsManager.AddNamespace("u", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

                idElem = doc.SelectSingleNode("//*[@u:Id=\"" + id + "\"]", nsManager) as XmlElement;
            }

            return idElem;
        }
    }

Exceptions

System.ServiceModel.Security.MessageSecurityException: Message security verification failed. 

---&amp;gt; System.Security.Cryptography.CryptographicException: The signature verification failed.
   at System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm hash, AsymmetricSignatureDeformatter deformatter, String signatureMethod)
   at System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verificationKey)
   at System.ServiceModel.Security.WSSecurityOneDotZeroReceiveSecurityHeader.VerifySignature(SignedXml signedXml, Boolean isPrimarySignature, SecurityHeaderTokenResolver resolver, Object signatureTarget, String id)
   at System.ServiceModel.Security.ReceiveSecurityHeader.ProcessPrimarySignature(SignedXml signedXml, Boolean isFromDecryptedSource)
   at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteSignatureEncryptionProcessingPass()
   at System.ServiceModel.Security.LaxModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses(ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader)
   at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
   at System.ServiceModel.Security.MessageSecurityProtocol.ProcessSecurityHeader(ReceiveSecurityHeader securityHeader, Message&amp;amp; message, SecurityToken requiredSigningToken, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
   at System.ServiceModel.Security.AsymmetricSecurityProtocol.VerifyIncomingMessageCore(Message&amp;amp; message, String actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
   at System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message&amp;amp; message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
   --- End of inner exception stack trace ---</ExceptionString><InnerException><ExceptionType>System.Security.Cryptography.CryptographicException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>The signature verification failed.</Message><StackTrace>   at System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm hash, AsymmetricSignatureDeformatter deformatter, String signatureMethod)
   at System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verificationKey)
   at System.ServiceModel.Security.WSSecurityOneDotZeroReceiveSecurityHeader.VerifySignature(SignedXml signedXml, Boolean isPrimarySignature, SecurityHeaderTokenResolver resolver, Object signatureTarget, String id)
   at System.ServiceModel.Security.ReceiveSecurityHeader.ProcessPrimarySignature(SignedXml signedXml, Boolean isFromDecryptedSource)
   at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteSignatureEncryptionProcessingPass()
   at System.ServiceModel.Security.LaxModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses(ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader)
   at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
   at System.ServiceModel.Security.MessageSecurityProtocol.ProcessSecurityHeader(ReceiveSecurityHeader securityHeader, Message&amp;amp; message, SecurityToken requiredSigningToken, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
   at System.ServiceModel.Security.AsymmetricSecurityProtocol.VerifyIncomingMessageCore(Message&amp;amp; message, String actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
   at System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message&amp;amp; message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)</StackTrace><ExceptionString>System.Security.Cryptography.CryptographicException: The signature verification failed.
   at System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm hash, AsymmetricSignatureDeformatter deformatter, String signatureMethod)
   at System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verificationKey)
   at System.ServiceModel.Security.WSSecurityOneDotZeroReceiveSecurityHeader.VerifySignature(SignedXml signedXml, Boolean isPrimarySignature, SecurityHeaderTokenResolver resolver, Object signatureTarget, String id)
   at System.ServiceModel.Security.ReceiveSecurityHeader.ProcessPrimarySignature(SignedXml signedXml, Boolean isFromDecryptedSource)
   at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteSignatureEncryptionProcessingPass()
   at System.ServiceModel.Security.LaxModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses(ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader)
   at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
   at System.ServiceModel.Security.MessageSecurityProtocol.ProcessSecurityHeader(ReceiveSecurityHeader securityHeader, Message&amp;amp; message, SecurityToken requiredSigningToken, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
   at System.ServiceModel.Security.AsymmetricSecurityProtocol.VerifyIncomingMessageCore(Message&amp;amp; message, String actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
   at System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message&amp;amp; message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)

SOAP

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <s:Header>
    <a:Action s:mustUnderstand="1" u:Id="_3">http://www.xxx.com/xxx/v1/submitRequest</a:Action>
    <a:MessageID u:Id="_4">urn:uuid:d9d6ae53-4e63-4e2d-86bf-954684d26fd8</a:MessageID>
    <a:To s:mustUnderstand="1" u:Id="_5">https://urigoeshere.com/</a:To>
    <a:From u:Id="_6">
      <a:Address>http://ourcompany.com/</a:Address>
    </a:From>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <u:Timestamp u:Id="uuid-01f867d2-f5c2-4587-a83d-0878a2342bd9-1">
        <u:Created>2013-01-21T17:12:31.213Z</u:Created>
        <u:Expires>2013-01-22T05:12:31.213Z</u:Expires>
      </u:Timestamp>
      <o:BinarySecurityToken u:Id="uuid-81deba4d-1a68-4f53-bb59-3c618914d683-2" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">OMITTED</o:BinarySecurityToken>
      <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:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">oNEIRj8uPIkIP4+BfAo/CmYDwzk=</o:KeyIdentifier>
          </o:SecurityTokenReference>
        </KeyInfo>
        <e:CipherData>
          <e:CipherValue>OMITTED</e:CipherValue>
        </e:CipherData>
        <e:ReferenceList>
          <e:DataReference URI="#_2"/>
        </e:ReferenceList>
      </e:EncryptedKey>
      <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">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>17c5Wuh9MNl4i/ytgwm9flLkAnY=</DigestValue>
          </Reference>
          <Reference URI="#_3">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>2YgeR5vFw0ICk8r+wiaVYknO4E8=</DigestValue>
          </Reference>
          <Reference URI="#_4">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>NepAQ8htbWWBy0ghljlVfMw5lr0=</DigestValue>
          </Reference>
          <Reference URI="#_5">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>ynr1icJszUi4OG5vt0usO0419As=</DigestValue>
          </Reference>
          <Reference URI="#_6">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>y8jXxE1bLmeg6vJi9iqKczNvEDo=</DigestValue>
          </Reference>
          <Reference URI="#uuid-01f867d2-f5c2-4587-a83d-0878a2342bd9-1">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>qlv+YHU/bxsWvEo/HYVZY9RfqQY=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>O6MK3Etk/OIXkSTngGaN+W1JPTrbV2/K0ulnTS69o1/NvmDfpdlkb67TR+UNnCBwVEiV0ILZfQkl9zVhMMpB0lOeM3zzJ5f97dh1WLkGeQm7U2G+ZTN0QFA/O4HZ2yADhzRlPLp29hNdjGBdky99b0oeFyU2hq8qdpIWwKMCDkHlGyftKb4t51yZSc+6uJKYhv3uXSmFMJAYZ6tlTfYa5Cc0jLileNx6I9+tyg73oJZsTEyc+cDZZqdxEmXLrAyt0kz0fcpGWrNKCrKuQlaMsV/KkJYVHSohPpJYWUrrtGmOfiWWhQuwlCIUIxCwR8HBpspFOK8IHEuu+kBQgKrx3g==</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-81deba4d-1a68-4f53-bb59-3c618914d683-2"/>
          </o:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </o:Security>
  </s:Header>
  <s:Body u:Id="_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <e:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
      <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
      <e:CipherData>
        <e:CipherValue>OMITTED</e:CipherValue>
      </e:CipherData>
    </e:EncryptedData>
  </s:Body>
</s:Envelope>

Upvotes: 2

Views: 5776

Answers (1)

PrzemekG
PrzemekG

Reputation: 96

Apart from enabling WCF security traces I can recommend you debugging .net framework code. To do this you have to configure VS as described here:

http://referencesource.microsoft.com/setup.html

You can also download framework source code and based on wcf traces examine what exactly is happening in part of code from where exceptions are thrown.

Upvotes: 1

Related Questions