C# HTTP WebRequest mit SSL-Handshake

Karbe

Rear Admiral
Registriert
Feb. 2008
Beiträge
5.399
Hi,
ich scheitere an der Authentifizierung an einer REST-API.
Die Authentifizierung soll über ein Client-Zertifikat erfolgen.
Dem Client übergebe ich das Zertifikat augenscheinlich korrekt, der SSL-Handshake scheitert aber, da auf der Gegenseite der Request ohne Zertifikat ankommt. Der Webserver gibt dann ein 401 - Not Authorized zurück.

Im Beispiel mit der Restsharp-Bibliothek, habe das aber auch (mit identischem Ergebnis) mit einem Standard HttpClient versucht.
Wer weiß Rat?

C#:
            var client = new RestClient(endpointURL);
            var request = new RestRequest(endpointResource, Method.POST);
            request.RequestFormat = DataFormat.Json;

            X509Certificate cert = new X509Certificate(@"\\Pfad\zum\CLientCertificate.crt");
            client.ClientCertificates = new X509CertificateCollection() { cert };

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            IRestResponse response = client.Execute(request);
            var content = response.Content;
 
Zuletzt bearbeitet:
Hast du Zugriff auf die Logs bzw. den Source Code vom Server? Das einfachste wäre wohl das ganze mal lokal zu debuggen also Client und Server. Ins Blaue geraten liegt’s aber wahrscheinlich am Zertifikat.
 
  • Gefällt mir
Reaktionen: Karbe
Interessant wäre sicherlich auch die genaue Antwort vom Server. Der Fehlercode kann vieles bedeuten und muss nichts zwangsläufig mit dem Zertifikat zusammenhängen (auch wenn das wahrscheinlich ist).
 
  • Gefällt mir
Reaktionen: Karbe
Auf das Log vom Webserver hab ich leider keinen Zugriff, hab nur einen Auszug erhalten:
Code:
ssl-access-VM2.access.log-20201209:xyz.xyz.xyz.xyz - - "08/Dec/2020 14:52:01.113 +0000" "POST /endpointResource HTTP/1.1" 401 181 "-" "-" 615 14683 0 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 sslclient_verified: NONE - client_cert_exp_date - client_serial - duration: 59461 - -

Ergänzung ()


Wenn ich den Request mit Fiddler anschaue, dann enthält der Body folgendes:
Code:
A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.

Version: 3.3 (TLS/1.2)
Random: 5F D2 2B 4F DC 9A 64 A6 4C 4D 3B ED C2 DD 7A 9E 34 23 A4 30 4B 31 F5 54 2E E6 48 1C 07 B7 4F DA
"Time": 03.02.2012 13:26:07
SessionID: empty
Extensions:
    server_name    EndpointUrl
    supported_groups    x25519 [0x1d], secp256r1 [0x17], secp384r1 [0x18]
    ec_point_formats    uncompressed [0x0]
    signature_algs    rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_sha1, dsa_sha1, rsa_pkcs1_sha512, ecdsa_secp521r1_sha512
    SessionTicket    empty
    extended_master_secret    empty
    renegotiation_info    00
Ciphers:
    [C02C]    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    [C02B]    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    [C030]    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    [C02F]    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    [009F]    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
    [009E]    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    [C024]    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    [C023]    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    [C028]    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    [C027]    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    [C00A]    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    [C009]    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    [C014]    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    [C013]    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
    [009D]    TLS_RSA_WITH_AES_256_GCM_SHA384
    [009C]    TLS_RSA_WITH_AES_128_GCM_SHA256
    [003D]    TLS_RSA_WITH_AES_256_CBC_SHA256
    [003C]    TLS_RSA_WITH_AES_128_CBC_SHA256
    [0035]    TLS_RSA_WITH_AES_256_CBC_SHA
    [002F]    TLS_RSA_WITH_AES_128_CBC_SHA
    [000A]    SSL_RSA_WITH_3DES_EDE_SHA

Compression:
    [00]    NO_COMPRESSION
 
Zuletzt bearbeitet:
Ich glaube nicht, dass der SSL-Handeshake das Problem ist. Vielmehr eine Zertifikatsprüfung auf Applikationsebene beim Server. Schau mal im Fiddler ob du da noch mehr Einträge bzgl. des POST request/response finden kannst.
 
  • Gefällt mir
Reaktionen: Karbe
Ich bin noch etwas in die Tiefe gegangen und habe festgestellt, daß der SSL-Stream gar keine LocalCertificates enthält. Die Ursache muss also beim Initialisieren des Streams durch den Client liegen, dort wird das Zertifikat scheinbar nicht übergeben.
Nur warum ist das so und wie kann ich das lösen?
 
Bin jetzt kein Experte. Aber Zertifikate werden neben der Authentifizierung
auch zur Überprüfung während des SSL Handshakes eingesetzt, ob einem HTTPS Server vertraut wird.
Das würde zumindest erklären, wieso dein Zertifikat nicht mitgeschickt wird.
Bist du dir sicher, dass das Zertifikat zur Authentifizierung eingesetzt wird?
Vlt. fehlt einfach nur ein API Key?
 
  • Gefällt mir
Reaktionen: Karbe
Das Problem lag tatsächlich am Zertifikat, es enthielt keinen Private-Key..
 
Der Post ist zwar schon etwas älter, aber seit wann enthalten Zertifikate private Schlüssel?
 
Alle Client Zertifikate enthalten private Schlüssel.
Aber zum Server geschickt werden sollten die PK nicht…

… ist vielleicht noch zu früh am Morgen, aber ich rieche eine Fehlkonfiguration auf Serverseite. 🤔
 

Ähnliche Themen

Zurück
Oben