2010-11-03 16 views
12

Próbuję uzyskać dostęp do publicznie hostowanej usługi WWW SOAP (nie WCF) za pośrednictwem protokołu HTTPS i pojawia się błąd, którego nigdy wcześniej nie widziałem. Po pierwsze, tutaj są fakty:Jak zmusić klienta WCF do wysłania certyfikatu klienta?

  • Ta usługa wymaga certyfikatów klienta. Mam certyfikat podpisany przez ten sam urząd certyfikacji co certyfikat serwera.
  • Wiem, że adres URL jest dostępny, ponieważ mogę go uruchomić w Internet Explorerze. IE wyświetla okno "wybierz certyfikat", a jeśli go wybiorę (i zignoruje błąd serwera-nazwa-hosta-nie-zgodności-certyfikatu), uruchomi się i da mi błąd HTTP 500.
  • Jeśli otworzę witrynę w Chrome, po wybraniu certyfikatu i zignorowaniu błędu otrzymam zwykły komunikat o błędzie dotyczący działania WSA = null.
  • Jeśli otworzę witrynę w FireFox, po zignorowaniu błędu otrzymam stronę o tym, że serwer nie mógł zweryfikować mojego certyfikatu. Nigdy mnie o to nie poprosił, więc ma to sens.

Teraz wyjątek:

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) 

Mam prześledzić interakcji z WireShark, ale ponieważ nie jestem ekspertem w protokole TLS, mogę być brakuje wskazówek, co się dzieje . Tu jednak jest to, co ja widzę:

  1. C -> S Client Witam
    • Zawiera takie rzeczy liczbę losową, data/czas, cypher apartamenty obsługiwane itp
  2. S - > C Server Witam, Certyfikat, żądania certyfikatu serwera Witam Sporządzono
    • Zawiera certyfikat serwera, a wniosek o certyfikat klienta
  3. C -> S Certyfikat Client Key Exchange, Change Cipher Spec, Encrypted Handshake Wiadomość
    • Oto interesująca część - Pierwsza część tego pakietu jest handshake certyfikatu, gdzie zakładam certyfikat klienta będzie być, ale nie ma żadnych certyfikatów (długość certyfikatów: 0).
  4. S -> C Alert (Level: Fatal Opis: Bad certyfikatu)
    • No tak, nie było świadectwo wysłana.

My wiążący jest skonfigurowana w następujący sposób:

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

Moje zachowanie jest skonfigurowana w następujący sposób:

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

Mój punkt końcowy jest skonfigurowany do korzystania zarówno wiązania i zachowanie. Dlaczego WCF odmawia wysłania certyfikatu, gdy tworzy połączenie https?

Odpowiedz

9

Rozwiązałem problem, ale nie rozumiem, dlaczego ta zmiana konfiguracji go naprawiła. Zmieniłem tę linię:

<httpsTransport useDefaultWebProxy="false" /> 

do tego:

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

i magicznie zaczęło działać. Zrozumiałem, że "gałka" requireClientCertificate była dla serwera, więc nie próbowałem tego podczas moich sporów. Najwyraźniej się myliłem.

+0

Nienawidzę WCF tak bardzo. To rozwiązanie sprawdziło się, dzięki hałdom - ale to wszystko jest takie skrzypiące. Zabij mnie. – robnick

-1

Może to być problem z negocjowaniem, który protokół bezpieczeństwa ma być używany.W szczególności im myśli, że serwer może nie lubić WCF próbując użyć TLS 1.0.

Aby sprawdzić, czy tak jest w przypadku próby dodania następuje przed wywołaniem usługi

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3 

To może być dodawany zarówno w kodzie klienta lub poprzez umieszczenie go w IEndpointBehavior

+0

Próbowałem tego i nie zmieniło to wyników. Wiem, że serwer obsługuje TLS 1.0 (i tylko jeden konkretny szyfr, w rzeczywistości, ale ten szyfr jest na liście wysyłanej do serwera podczas uzgadniania). – Mark

+0

Nie, jeśli wymiana dotarła do wiadomości ChangeCipherSpec. Oznacza to, że uzgodniono wszystko na temat protokołu. – EJP

2

Nie powinno być a CertificateRequest z serwera, określając dopuszczalne typy certyfikatów i urzędy certyfikacji. Jeśli twój certyfikat nie pasuje do tych, nie zostanie wysłany.

+0

Wystąpiło żądanie certyfikatu (patrz # 2) i rzeczywiście zawierało listę urzędów certyfikacji i typów certyfikatów. Rzeczywiście mam odpowiedni certyfikat i jest on określony w tym zachowaniu. – Mark

+0

Jeśli wszystko to jest prawdą, po komunikacie CertificateRequest z serwera pojawiłby się komunikat Certificate od klienta. Nieunikniony wniosek jest taki, że niektóre z nich nie są prawdziwe. Musisz dokładnie sprawdzić wszystko: konkretnie, że certyfikat (a) jest dostępny dla aplikacji i (b) jest zgodny ze wszystkimi ograniczeniami wyrażonymi w CertificateRequest. – EJP

+0

Jest to weryfikowalne, prawda ... Mam tutaj przechwytywanie WireShark. W końcu udało mi się rozwiązać problem, ale tak naprawdę nie rozumiem, dlaczego to, co zmieniłem, naprawiło to. Opublikuję to w osobnej odpowiedzi. – Mark

Powiązane problemy