English 中文(简体)
WCF service certificate and client side endpoint identity - why it doesn t work?
原标题:

[Update] - I attach also full config files, for service, and for client (outside of here, not to flood the topic)

I m having situation pretty much identical to the one outlined in this question, however my question is somewhat different.

  • I m using NetTcpBinding with security set to TransportWithMessageCredential
  • I m using Password/Username credentials backed up by ASP.NET provider
  • My service is self hosted in Windows Service
  • I do have in my endpoint behavior specified authentication revocationMode="NoCheck"

It is required that the service provides a certificate to authenticate itself to clients. That s OK, I just do:

<serviceCertificate findValue="***"
                    storeLocation="CurrentUser"
                    storeName="My"
                    x509FindType="FindByThumbprint"/>

Now, I somewhat imagined that now the client would end up having

<identity>
  <certificate encodedValue="encoded certificate"/>
</identity>

And it will be able to verify service s credentials without having that certificate installed in the store on client machine.

I was surprised to learn that although I set the service credentials to certificate, WSDL exposes

<Identity>
   <Dns>Foo</Dns>
</Identity>

Again, on service I can set Identity to CertificateReference and hook it up to the same certificate, and then WSDL will expose identity as X509Certificate, but when I run the client that setting is ignored, and I end up with error message:

System.ServiceModel.Security.SecurityNegotiationException: The X.509 certificate CN=xxx is not in the trusted people store. The X.509 certificate CN=xxx chain building failed. The certificate that was used has a trust chain that can not be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.

Is there a way to make client use that value from config and work without having to install a service certificate (nor its root) on client machine?

[UPDATE] While setting certificateValidationMode to none will make the exception go away, it is unacceptable solution from security point of view.

It makes the client merely acknowledge that it receive some certificate, without getting into details. This makes all range of man in the middle attacks possible. It still won t validate the information sent by (alleged) service against the certificate dumped in the config.

最佳回答

Solution sketch:

1) Define and register a custom X509CertificateValidator on the client

2) In the Validate method, compare the given certificate with the one present in the client s EndpointAddress.Identity property. The object referenced by this property should have the X509CertificateEndpointIdentity exact type.

I didn t test this solution, however it makes perfect sense to me.

HTH Pedro

问题回答

[UPDATE] While setting certificateValidationMode to none will make the exception go away, it is unacceptable solution from security point of view.

It makes the client merely acknowledge that it receive some certificate, without getting into details. This makes all range of man in the middle attacks possible. It still won t validate the information sent by (alleged) service against the certificate dumped in the config.

You are wrong. This will do perfectly. That s actually what you want - your certificate to not be validated. All you need is to set the identity of the endpoint on the client to

<identity>
  <certificate encodedValue="encoded certificate"/>
</identity>

When the client connects to the server WCF will compare the two certificates and throw an exception if they do not match. And you are perfectly safe.

Using a custom validator like Pedro Felix suggested is completely unnecessary in your case. That s exactly what the endpoint identity is for.

Sorry, I cannot comment on other answers.

I just tested this in .NET 4.0 and I can confirm that the "Zeratul" s answer is correct. Explicitly settings the identity of the service either in config, or programmatically is sufficient for server authentication. There is no need to validate certificate by any other means (i.e. you can set "certificateValidationMode" to "None") since you are using the ultimate validation method - comparison of the thumbprint of the certificate.

@AlexDrenea

"serviceCertificate" is not used for validation. It is used with message security to encrypt messages before they are sent to the server. See Microsoft s documentation about this:

http://msdn.microsoft.com/en-us/library/ms731782.aspx

This is an additional comment to my previous answer. Sorry I cannot comment answers.

Moreover you do not need to set any identity on the server. Forget about what WSDL tells you about the identity of the server. The identity of a remote service endpoint is decided by the client during runtime. If the server uses SSL then it has several identities: the common name of the certificate (i.e. a DNS identity), a certificate identity and an RSA identity (not sure about the last one). Therefore, you can check the server s identity by anyone of these criteria (or by several of them).

You are corect and almost finished configuring the client configuration. You are missing one last thing (as mentioned in the error description) : you need to set the revocationMode to NoCheck in the configuration:

 <behaviors>
  <endpointBehaviors>
    <behavior name="SecureMessageUserName">
      <clientCredentials>
         <serviceCertificate>
            <authentication revocationMode="NoCheck"/>
         </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
 </behaviors>

If you need more details, just let me know and I ll post a full working client configuration.

Edit sorry for the delay

You should also add the noCheck in the server configuration :

<behavior name="X509SecureBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <serviceCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="aaaa" />
            <clientCertificate>
              <authentication certificateValidationMode="None" revocationMode="NoCheck" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>

Also I didn t include the certificate reference in the endpoint definition.





相关问题
Signed executables under Linux

For security reasons, it is desirable to check the integrity of code before execution, avoiding tampered software by an attacker. So, my question is How to sign executable code and run only trusted ...

MALICIOUS_CODE EI_EXPOSE_REP Medium

I run findbugs against all of my code and only tackle the top stuff. I finally got the top stuff resolved and now am looking at the details. I have a simple entity, say a user: public class User ...

XSS on jsbin.com

Anyone know if jsbin.com implements any protection for XSS or other javascript attacks? I see jsbin links used fairly regularly on sites like this one and I can t find any indication from the site ...

Make md5 strong

Im making a website that will intergrate with game that only support md5 hashing metod (atm). Which ofc is not especially safe anymore. But how could i make it stronger? Should I just generate long ...

Why running a service as Local System is bad on windows?

I am trying to find out the difference between difference service account types. I tumbled upon this question. The answer was because it has powerful access to local resources, and Network Service ...

Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

热门标签