wcf Error: Incoming message was signed with a token which is different from what used to encrypt body. This was not expected

半世苍凉 提交于 2020-01-04 20:47:58

问题


I am trying to call a third party service with a verisign test x.509 certificate. When I get the response message back, it generates the following error:

Incoming message was signed with a token which is different from what used to encrypt body. This was not expected

This error was not expected by me because I only supplied the service the one x.509 certificate. What other certificate is it using?

Any insight would be appreciated!

My custom binding look like:

<binding name="NodalCustomBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
        receiveTimeout="00:10:00" sendTimeout="00:10:00">
      <textMessageEncoding messageVersion="Soap11" />
      <security
        authenticationMode="MutualCertificate"
        requireDerivedKeys="false"
        includeTimestamp="true"
         keyEntropyMode="ClientEntropy"
        messageProtectionOrder="SignBeforeEncrypt"
        messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
        requireSecurityContextCancellation="false"
        allowSerializedSigningTokenOnReply="true"
        enableUnsecuredResponse="true" >
        <secureConversationBootstrap />
      </security>
      <httpsTransport />
    </binding>

My Endpoint behavoir looks like:

<endpointBehaviors>
    <behavior name="NodalCredentialBehavior">   
      <clientCredentials>
        <clientCertificate findValue="Testx509"                                
          storeLocation="CurrentUser"
         storeName="My"
          x509FindType="FindBySubjectName"/>
        <serviceCertificate>
          <authentication certificateValidationMode="None"/>
          <defaultCertificate findValue="Testx509"
          storeLocation="CurrentUser"
           storeName="My"
          x509FindType="FindBySubjectName" />
        </serviceCertificate>
      </clientCredentials>          
    </behavior>
  </endpointBehaviors>

and finally my response message looks like:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Header>
   <wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <wsse:BinarySecurityToken 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="SecurityToken-b1a3e7ef-008e-6bc0-b779-69cc8bf72d39Q</wsse:BinarySecurityToken>
  <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
    <dsig:SignedInfo>
      <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <dsig:Reference URI="#Id-b75df9d2-5a50-d36b-b26a-08ee4065010d">
        <dsig:Transforms>
          <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        </dsig:Transforms>
        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <dsig:DigestValue>YKW87r6WtI5b5Mx3D/WIPg2bcIk=</dsig:DigestValue>
      </dsig:Reference>
    </dsig:SignedInfo>
    <dsig:SignatureValue>lAB8mXepN63lGSk/lraYooTEFfn8dnwiJ89z8d5S6HKsDjAgg=    </dsig:SignatureValue>
    <dsig:KeyInfo>
      <SecurityTokenReference xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:Reference URI="#SecurityToken-b1a3e7ef-008e-6bc0-b779-69cc8bf72d39" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
      </SecurityTokenReference>
    </dsig:KeyInfo>
  </dsig:Signature>
</wsse:Security>
</SOAP-ENV:Header>
  <SOAP-ENV:Body wsu:Id="Id-b75df9d2-5a50-d36b-b26a-08ee4065010d" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
   <ns0:ResponseMessage xmlns:ns0="http://www.ercot.com/schema/2007-06/nodal/ews/message">
  <ns0:Header>
    <ns0:Verb>reply</ns0:Verb>
    <ns0:Noun/>
    <ns0:ReplayDetection>
      <ns0:Nonce/>
      <ns0:Created/>
    </ns0:ReplayDetection>
    <ns0:Revision>001</ns0:Revision>
    <ns0:Source/>
    <ns0:UserID>API</ns0:UserID>
  </ns0:Header>
  <ns0:Reply>
    <ns0:ReplyCode>FATAL</ns0:ReplyCode>
    <ns0:Error>Invalid Verb</ns0:Error>
    <ns0:Timestamp>2012-03-14T10:54:31.701-05:00</ns0:Timestamp>
  </ns0:Reply>
</ns0:ResponseMessage>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

回答1:


I found the answer. It was a problem with the certificates and the configuration.

Certificates Apparently, I needed two x.509 certificates one for the request and one for the response.

  1. In explorer, double click your cer file to open it.
  2. Click on the "Certification Path" tab and make note of hierarchy
  3. Install both x.509 certificates in the Personal Certificates folder.
  4. In MMC, double click the certificate to open it
  5. Click on the "Certification Path" tab and make sure path matches paths in step 2

Certificates should be set up correctly now.

Configuration

Create an endpoint behavior in the app.config and create an identity

<behaviors>
  <endpointBehaviors>
    <behavior name="myBehavior">   
      <clientCredentials>
        <clientCertificate findValue="#RequestCertificate#"                                
          storeLocation="CurrentUser"
         storeName="My"
          x509FindType="FindBySubjectName"/>
        <serviceCertificate>
          <authentication certificateValidationMode="ChainTrust"/>
          <defaultCertificate findValue="#ResponseCertificate#"
          storeLocation="CurrentUser"
           storeName="My"
          x509FindType="FindBySubjectName" />
        </serviceCertificate>
      </clientCredentials>          
    </behavior>

  <endpoint address="https://myaddress.com/" binding="customBinding"
            contract="mycontract"
            behaviorConfiguration="myBehavior"
            name="HttpEndPoint">
    <identity>
      <dns value="#ResponseCertificate" />
    </identity>        
  </endpoint>

where:

#RequestCertificate# is the name of your request certificate

#ResponseCertificate# is the name of your response certificate




回答2:


Keith After you mentioned chaintrust, i looked and low and behold, i was using the root certificate of my API certificate as the other certificate that I was trying to validate the response against (I feel really stupid on that point). I then linked to the correct certificate and got a new error:

No timestamp is available in the security header to do replay detection.

To fix this had to modify your custom binding a bit by adding the "localClientSettings" tag below the "secureConversationBootstrap" tag

<binding name="NodalCustomBinding" closeTimeout="00:01:00" openTimeout="00:01:00" 
    receiveTimeout="00:10:00" sendTimeout="00:10:00"> 
  <textMessageEncoding messageVersion="Soap11" /> 
  <security 
    authenticationMode="MutualCertificate" 
    requireDerivedKeys="false" 
    includeTimestamp="true" 
     keyEntropyMode="ClientEntropy" 
    messageProtectionOrder="SignBeforeEncrypt" 
    messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" 
    requireSecurityContextCancellation="false" 
    allowSerializedSigningTokenOnReply="true" 
    enableUnsecuredResponse="true" > 
    <secureConversationBootstrap /> 
    <localClientSettings detectReplays="false"/>
  </security> 
  <httpsTransport /> 
</binding> 

I did this per the recomendation at http://social.msdn.microsoft.com/forums/en-US/wcf/thread/3be779e7-1d73-455c-8aa0-cb90026e8993/. Thanks again for the help. Its amazing how one little word will put you down the right path.




回答3:


Just had a similar problem and think this could help other thread-trawlers:

In the service (policy) add: <sp:RequireThumbprintReference/> under policy example:

<wsp:Policy>
    <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-      securitypolicy/200702/IncludeToken/AlwaysToRecipient">
    <wsp:Policy>
        <sp:RequireThumbprintReference/>
        <sp:WssX509V3Token10/>
    </wsp:Policy>
    </sp:X509Token>
</wsp:Policy>

This will ensure correctness of the SecurityTokenReference




回答4:


The certificate wich its argued about might be present in the same SOAP response. I used Fiddler (freeware licensed) program to sniff the SOAP response and I got the certificated in base64 inside a node BinarySecurityToken. I save it as .cer in a notepad and I installed in the proper cert store. Then set up my config and my Wcf client worked fine.



来源:https://stackoverflow.com/questions/9571058/wcf-error-incoming-message-was-signed-with-a-token-which-is-different-from-what

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!