title: WCF – SSL – Client authentication - Can’t implement it on Windows 7, while I can on Windows XP
body: <p>I’m trying to make a wcf client and server (self hosted) with ssl (transport security) both ways -  server certificate and client certificate.</p>
  
  <p>In windows XP everything works, but in Windows 7 it failed with client certificate.
  If the server is on winXp, and the client is on win7 – it’ll work, the opposite – it won’t work.</p>
  
  <p>Here is app.config of the server:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;configuration&gt;
    &lt;system.serviceModel&gt;
      &lt;behaviors&gt;
        &lt;serviceBehaviors&gt;         
          &lt;/behavior&gt;
          &lt;behavior name="NewBehavior1"&gt;
            &lt;serviceMetadata httpsGetEnabled="true"/&gt;
            &lt;serviceCredentials&gt;
              &lt;serviceCertificate findValue="ServerCert" storeName="My" x509FindType="FindBySubjectName" /&gt;
              &lt;clientCertificate&gt;
                &lt;authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck" trustedStoreLocation="LocalMachine" /&gt;
              &lt;/clientCertificate&gt;
              &lt;windowsAuthentication allowAnonymousLogons="True"/&gt;
            &lt;/serviceCredentials&gt;
  
          &lt;/behavior&gt;
        &lt;/serviceBehaviors&gt;
      &lt;/behaviors&gt;
      &lt;bindings&gt;
        &lt;basicHttpBinding&gt;
          &lt;binding name="Binding1"&gt;
            &lt;security mode="Transport"&gt;
             &lt;transport clientCredentialType="Certificate" proxyCredentialType="None" realm=""/&gt;
            &lt;/security&gt;
          &lt;/binding&gt;
        &lt;/basicHttpBinding&gt;
  
      &lt;/bindings&gt;
      &lt;services&gt;
        &lt;service behaviorConfiguration="NewBehavior1"
              name="Service.Calc"&gt;
          &lt;endpoint
            address="https://172.18.96.116:8413/MyCalcService1"
            binding="basicHttpBinding"
            bindingConfiguration="Binding1"
            name="TestWCFService.Http"
            contract="Contarcts.ICalc" /&gt;
          &lt;host&gt;
            &lt;baseAddresses&gt;
              &lt;add baseAddress="https://172.18.96.116:8413/MyCalcService1" /&gt;
            &lt;/baseAddresses&gt;
          &lt;/host&gt;
        &lt;/service&gt;
      &lt;/services&gt;
    &lt;/system.serviceModel&gt;
  
  &lt;/configuration&gt;
  </code></pre>
  
  <p>Client:</p>
  
  <pre><code>&lt;system.serviceModel&gt;
      &lt;behaviors&gt;
        &lt;endpointBehaviors&gt;
          &lt;behavior name="clientBehavior1"&gt;
            &lt;clientCredentials&gt;
              &lt;clientCertificate findValue="ClientCert"
                   storeLocation="LocalMachine"
                   storeName="My"
                   x509FindType="FindBySubjectName" /&gt;
            &lt;/clientCredentials&gt;
          &lt;/behavior&gt;
        &lt;/endpointBehaviors&gt;
      &lt;/behaviors&gt;
  
      &lt;bindings&gt;
        &lt;basicHttpBinding&gt;
          &lt;binding name="TestWCFService.Http1"&gt;
            &lt;security mode="Transport"&gt;
            &lt;transport clientCredentialType="Certificate" /&gt;
            &lt;/security&gt;
          &lt;/binding&gt;
        &lt;/basicHttpBinding&gt;
      &lt;/bindings&gt;
      &lt;client&gt;
        &lt;endpoint address="https://172.18.96.116:8413/MyCalcService1"
        binding="basicHttpBinding"
        bindingConfiguration="TestWCFService.Http1"
        contract="CalcProxy.ICalc"
        name="TestWCFService.WSHttp1"
        behaviorConfiguration="clientBehavior1"
        /&gt;
      &lt;/client&gt;
    &lt;/system.serviceModel&gt;
  </code></pre>
  
  <p>Server’s code:</p>
  
  <pre><code>ServiceHost calcHost = new ServiceHost(typeof(Calc));
  calcHost.Open();
  </code></pre>
  
  <p>Client’s code:</p>
  
  <pre><code>System.Net.ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
  
  
  CalcClient proxy = new CalcClient();
  int res = proxy.Add(2, 4);
  </code></pre>
  
  <p>My makecert commands are:</p>
  
  <pre><code>makecert -sv SignRoot.pvk -cy authority -r MyCA.cer -a sha1 -n "CN=MyCA" -ss my -sr localmachine
  
  makecert -iv SignRoot.pvk -ic MyCA.cer -cy end -pe -n CN="ClientCert" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
  
  makecert -iv SignRoot.pvk -ic MyCA.cer -cy end -pe -n CN="ServerCert" -eku 1.3.6.1.5.5.7.3.2 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
  </code></pre>
  
  <hr>
  
  <p>I also validated that the ca is in the right location (Local computer - Trusted root CA), and the server/client certificates also in the right location (Local computer - Personal).</p>
  
  <p>The private keys can be exportable and I validated that “Everyone” has permissions to private keys (C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys).</p>
  
  <p>It works via fiddler.</p>
  
  <hr>
  
  <p>The errors I get from SvcTraceViewer:</p>
  
  <p>Client side - <strong>The HTTP request was forbidden with client authentication scheme 'Anonymous'.</strong></p>
  
  <p>Server side - <strong>Client certificate is required. No certificate was found in the request.</strong></p>
  
  <p>Error from http trace: <strong>Attempt by server application to receive client certificate failed with status: 0xC0000225.</strong></p>
  
  <p>Similar problem I’ve found, but I still stuck though:
  <a href="https://stackoverflow.com/questions/9858275/net-application-fails-to-send-client-certificate-win-7-vs-win-xp">.NET application fails to send client certificate - Win 7 vs Win XP?</a></p>
  
  <p>How can I make it work on Windows 7?</p>
  
  <p>Thanks.</p>