Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
571 views
in Technique[技术] by (71.8m points)

https - How to force WCF client to send client certificate?

I'm trying to access a publicly-hosted SOAP web service (not WCF) over https, and I'm getting an error that I've never seen before. First, here are the facts:

  • This service requires client certificates. I have a certificate that is signed by the same CA as the server's certificate.
  • I know that the URL is available, as I can hit it in Internet Explorer. IE brings up the "choose certificate" window, and if I pick it (and ignore the server-host-name-does-not-match-certificate error), it goes on and gives me an HTTP 500 error.
  • If I open the site in Chrome, after picking the cert and ignoring the error, I get a normal error message about WSA Action = null.
  • If I open the site in FireFox, after ignoring the error, I get a page about how the server couldn't validate my certificate. It never asked me to pick one, so that makes perfect sense.

Now, the exception:

Error occurred while executing test 12302: System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'ihexds.nist.gov:9085'. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
   at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

I've traced the interaction with WireShark, but because I'm not an expert in the TLS protocol, I could be missing clues as to what's going on. Here, however, is what I do see:

  1. C -> S Client Hello
    • Contains things like a random number, date/time, cypher suites supported, etc
  2. S -> C Server Hello, Certificate, Certificate Request, Server Hello Done
    • Contains the server's certificate, and a request for a client certificate
  3. C -> S Certificate, Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
    • HERE IS THE INTERESTING PART -- The first part of this packet is the Certificate handshake, where I assume the client certificate would be, but there are no certificates present (Certificates Length: 0).
  4. S -> C Alert (Level: Fatal, Description: Bad Certificate)
    • Well, yeah, there was no certificate sent.

My binding is set up as follows:

<binding name="https_binding">
    <textMessageEncoding />
    <httpsTransport useDefaultWebProxy="false" />
</binding>

My behavior is set up as follows:

<behavior name="clientcred">
    <clientCredentials>
        <clientCertificate findValue="69b6fbbc615a20dc272a79caa201fe3f505664c3" storeLocation="CurrentUser" storeName="My" x509FindType="FindByThumbprint" />
        <serviceCertificate>
            <authentication certificateValidationMode="None" revocationMode="NoCheck" />
        </serviceCertificate>
    </clientCredentials>
    <messageInspector />
</behavior>

My endpoint is set up to use both the binding and the behavior. Why does WCF refuse to send the certificate when it creates the https connection?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I solved the problem, but I do not understand why this configuration change fixed it. I changed this line:

<httpsTransport useDefaultWebProxy="false" />

to this:

<httpsTransport useDefaultWebProxy="false" requireClientCertificate="true" />

and magically it started working. I had understood that the requireClientCertificate "knob" was for server-side, so I hadn't tried it during my wrangling. Apparently I was wrong.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...